
<!DOCTYPE HTML>
<html lang="zh-hans" >
    <head>
        <meta charset="UTF-8">
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <title>四、Spring Boot 特性 · Spring Boot 中文文档</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="description" content="">
        <meta name="generator" content="GitBook 3.2.3">
        <meta name="author" content="lichongbing.com">
        
        
    
    <link rel="stylesheet" href="../gitbook/style.css">

    
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-splitter/splitter.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-tbfed-pagefooter/footer.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-search-plus/search.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-prism/prism-twilight.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-fontsettings/website.css">
                
            
        

    

    
        
    
        
    
        
    
        
    
        
    
        
    

        
    
    
    
    <meta name="HandheldFriendly" content="true"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon-precomposed" sizes="152x152" href="../gitbook/images/apple-touch-icon-precomposed-152.png">
    <link rel="shortcut icon" href="../gitbook/images/favicon.ico" type="image/x-icon">

    
    <link rel="next" href="spring-boot-features.html" />
    
    
    <link rel="prev" href="using-spring-boot.html" />
    

    <style>
    @media only screen and (max-width: 640px) {
        .book-header .hidden-mobile {
            display: none;
        }
    }
    </style>
    <script>
        window["gitbook-plugin-github-buttons"] = {"repo":"lichongbing/springboot","types":["star","watch"],"size":"small"};
    </script>

    </head>
    <body>
        
<div class="book">
    <div class="book-summary">
        
            
<div id="book-search-input" role="search">
    <input type="text" placeholder="输入并搜索" />
</div>

            
                <nav role="navigation">
                


<ul class="summary">
    
    

    

    
        
        
    
        <li class="chapter " data-level="1.1" data-path="../">
            
                <a href="../">
            
                    
                    Introduction
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2" data-path="boot-documentation.html">
            
                <a href="boot-documentation.html">
            
                    
                    前言
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3" data-path="boot-documentation.html">
            
                <a href="boot-documentation.html#boot-documentation">
            
                    
                    一、Spring Boot 文档
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.3.1" data-path="boot-documentation.html">
            
                <a href="boot-documentation.html#boot-documentation-about">
            
                    
                    1、关于本文档
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.2" data-path="boot-documentation.html">
            
                <a href="boot-documentation.html#boot-documentation-getting-help">
            
                    
                    2、获取帮助
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.3" data-path="boot-documentation.html">
            
                <a href="boot-documentation.html#boot-documentation-first-steps">
            
                    
                    3、起步
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.4" data-path="boot-documentation.html">
            
                <a href="boot-documentation.html#_working_with_spring_boot">
            
                    
                    4、使用 Spring Boot
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.5" data-path="boot-documentation.html">
            
                <a href="boot-documentation.html#_learning_about_spring_boot_features">
            
                    
                    5、了解 Spring Boot 的新特性
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.6" data-path="boot-documentation.html">
            
                <a href="boot-documentation.html#_moving_to_production">
            
                    
                    6、生产环境
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.3.7" data-path="boot-documentation.html">
            
                <a href="boot-documentation.html#_advanced_topics">
            
                    
                    7、高级内容
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.4" data-path="getting-started.html">
            
                <a href="getting-started.html">
            
                    
                    二、入门
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.4.1" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-introducing-spring-boot">
            
                    
                    8、Spring Boot 简介
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.2" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-system-requirements">
            
                    
                    9、系统要求
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.4.2.1" data-path="getting-started.html">
            
                <a href="getting-started.html#_servlet_containers">
            
                    
                    9.1、Servlet 容器
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.4.3" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-installing-spring-boot">
            
                    
                    10、安装 Spring Boot
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.4.3.1" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-installation-instructions-for-java">
            
                    
                    10.1、针对 Java 开发人员的安装说明
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.4.3.1.1" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-maven-installation">
            
                    
                    10.1.1、Maven 安装
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.3.1.2" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-gradle-installation">
            
                    
                    10.1.2、Gradle 安装
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.4.3.2" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-installing-the-cli">
            
                    
                    10.2、安装 Spring Boot CLI
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.4.3.2.1" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-manual-cli-installation">
            
                    
                    10.2.1、手动安装
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.3.2.2" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-sdkman-cli-installation">
            
                    
                    10.2.2、使用 SDKMAN! 安装
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.3.2.3" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-homebrew-cli-installation">
            
                    
                    10.2.3、使用 OSX Homebrew 安装
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.3.2.4" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-macports-cli-installation">
            
                    
                    10.2.4、使用 MacPorts 安装
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.3.2.5" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-cli-command-line-completion">
            
                    
                    10.2.5、命令行完成
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.3.2.6" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-cli-example">
            
                    
                    10.2.6、快速入门 Spring CLI 示例
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.4.3.3" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-upgrading-from-an-earlier-version">
            
                    
                    10.3、升级旧版 Spring Boot
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.4.4" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-first-application">
            
                    
                    11、开发第一个 Spring Boot 应用
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.4.4.1" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-first-application-pom">
            
                    
                    11.1、 创建 POM
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.4.2" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-first-application-dependencies">
            
                    
                    11.2、 添加 Classpath 依赖
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.4.3" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-first-application-code">
            
                    
                    11.3、 编码
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.4.4.3.1" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-first-application-annotations">
            
                    
                    11.3.1、@RestController 与 @RequestMapping 注解
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.4.3.2" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-first-application-auto-configuration">
            
                    
                    11.3.2、@EnableAutoConfiguration 注解
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.4.3.3" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-first-application-main-method">
            
                    
                    11.3.3、main 方法
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.4.4.4" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-first-application-run">
            
                    
                    11.4、运行示例
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.4.4.5" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-first-application-executable-jar">
            
                    
                    11.5、创建可执行 jar
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.4.5" data-path="getting-started.html">
            
                <a href="getting-started.html#getting-started-whats-next">
            
                    
                    12、下一步
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html">
            
                    
                    三、使用 Spring Boot
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.1" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-build-systems">
            
                    
                    13、构建系统
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.1.1" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-dependency-management">
            
                    
                    13.1、依赖管理
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.1.2" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-maven">
            
                    
                    13.2、Maven
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.1.2.1" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-maven-parent-pom">
            
                    
                    13.2.1、继承 Starter Parent
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.1.2.1.1" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-maven-without-a-parent">
            
                    
                    13.2.2、不使用父 POM
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.1.2.1.2" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-maven-plugin">
            
                    
                    13.2.3、使用 Spring Boot Maven 插件
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5.1.3" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-gradle">
            
                    
                    13.3、Gradle
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.1.4" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-ant">
            
                    
                    13.4、Ant
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.1.5" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-starter">
            
                    
                    13.5、Starter
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5.2" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-structuring-your-code">
            
                    
                    14、组织代码
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.2.1" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-using-the-default-package">
            
                    
                    14.1、使用 default 包
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.2.2" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-locating-the-main-class">
            
                    
                    14.2、定位主应用类
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5.3" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-configuration-classes">
            
                    
                    15、配置类
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.3.1" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-importing-configuration">
            
                    
                    15.1、导入额外的配置类
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.3.2" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-importing-xml-configuration">
            
                    
                    15.2、导入 XML 配置
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5.4" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-auto-configuration">
            
                    
                    16、自动配置
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.4.1" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-replacing-auto-configuration">
            
                    
                    16.1、平滑替换自动配置
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.4.2" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-disabling-specific-auto-configuration">
            
                    
                    16.2、禁用指定的自动配置类
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5.5" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-spring-beans-and-dependency-injection">
            
                    
                    17、Spring Bean 与依赖注入
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.6" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-using-springbootapplication-annotation">
            
                    
                    18、使用 @SpringBootApplication 注解
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.7" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-running-your-application">
            
                    
                    19、运行您的应用
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.7.1" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-running-your-application">
            
                    
                    19.1、使用 IDE 运行
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.7.2" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-running-as-a-packaged-application">
            
                    
                    19.2、作为打包应用运行
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.7.3" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-running-with-the-maven-plugin">
            
                    
                    19.3、使用 Maven 插件
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.7.4" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-running-with-the-gradle-plugin">
            
                    
                    19.4、使用 Gradle 插件
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.7.5" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-hot-swapping">
            
                    
                    19.5、热交换
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5.8" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools">
            
                    
                    20、开发者工具
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.8.1" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-property-defaults">
            
                    
                    20.1、Property 默认值
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.8.2" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-restart">
            
                    
                    20.2、自动重启
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.8.2.1" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-restart-logging-condition-delta">
            
                    
                    20.2.1、条件评估变更日志
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.8.2.2" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-restart-exclude">
            
                    
                    20.2.2、排除资源
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.8.2.3" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-restart-additional-paths">
            
                    
                    20.2.3、监视附加路径
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.8.2.4" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-restart-disable">
            
                    
                    20.2.4、禁用重启
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.8.2.5" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-restart-triggerfile">
            
                    
                    20.2.5、使用触发文件
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.8.2.6" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-customizing-classload">
            
                    
                    20.2.6、自定义重启类加载器
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.8.2.7" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-known-restart-limitations">
            
                    
                    20.2.7、已知限制
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5.8.3" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-livereload">
            
                    
                    20.3、LiveReload
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.8.4" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-globalsettings">
            
                    
                    20.4、全局设置
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.8.5" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-remote">
            
                    
                    20.5、远程应用
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.5.8.5.1" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#_running_the_remote_client_application">
            
                    
                    20.5.1、运行远程客户端应用
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.8.5.2" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-devtools-remote-update">
            
                    
                    20.5.2、远程更新
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.5.9" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-packaging-for-production">
            
                    
                    21、打包生产应用
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.5.10" data-path="using-spring-boot.html">
            
                <a href="using-spring-boot.html#using-boot-whats-next">
            
                    
                    22、下一步
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features">
            
                    
                    四、Spring Boot 特性
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-application">
            
                    
                    23、SpringApplication
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.1.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-startup-failure">
            
                    
                    23.1、启动失败
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.1.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-banner">
            
                    
                    23.2、自定义 banner
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.1.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-customizing-spring-application">
            
                    
                    23.3、自定义 SpringApplication
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.1.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-customizing-spring-application">
            
                    
                    23.4、Fluent Builder API
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.1.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-application-events-and-listeners">
            
                    
                    23.5、应用程序事件与监听器
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.1.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-web-environment">
            
                    
                    23.6、Web 环境
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.1.7" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-application-arguments">
            
                    
                    23.7、访问应用程序参数
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.1.8" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-command-line-runner">
            
                    
                    23.8、使用 ApplicationRunner 或 ApplicationRunner
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.1.9" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-application-exit">
            
                    
                    23.9、应用程序退出
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.1.10" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-application-admin">
            
                    
                    23.10、管理功能
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config">
            
                    
                    24、外部化配置
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.2.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-random-values">
            
                    
                    24.1、配置随机值
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-command-line-args">
            
                    
                    24.2、访问命令行属性
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-application-property-files">
            
                    
                    24.3、应用程序属性文件
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-profile-specific-properties">
            
                    
                    24.4、特定 Profile 的属性文件
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-placeholders-in-properties">
            
                    
                    24.5、属性中的占位符
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-encrypting-properties">
            
                    
                    24.6、加密属性
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.7" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-yaml">
            
                    
                    24.7、使用 YAML 代替属性文件
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.2.7.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-loading-yaml">
            
                    
                    24.7.1、加载 YAML
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.7.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-exposing-yaml-to-spring">
            
                    
                    24.7.2、在 Spring Environment 中将 YAML 暴露为属性
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.7.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-multi-profile-yaml">
            
                    
                    24.7.3、多 profile YAML 文档
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.7.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-yaml-shortcomings">
            
                    
                    24.7.4、YAML 的缺点
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.2.8" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-typesafe-configuration-properties">
            
                    
                    24.8、类型安全的配置属性
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.2.8.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-3rd-party-configuration">
            
                    
                    24.8.1、第三方配置
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.8.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-relaxed-binding">
            
                    
                    24.8.2、宽松绑定
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.8.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-complex-type-merge">
            
                    
                    24.8.3、合并复杂类型
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.8.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-conversion">
            
                    
                    24.8.4、属性转换
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.2.8.4.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-conversion-duration">
            
                    
                    转换 duration
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.8.4.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-conversion-datasize">
            
                    
                    转换 Data Size
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.2.8.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-validation">
            
                    
                    24.8.5、@ConfigurationProperties 验证
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.2.8.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-external-config-vs-value">
            
                    
                    24.8.6、@ConfigurationProperties 与 @Value 对比
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-profiles">
            
                    
                    25、Profile
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.3.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-adding-active-profiles">
            
                    
                    25.1、添加激活 Profile
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.3.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-programmatically-setting-profiles">
            
                    
                    25.2、以编程方式设置 Profile
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.3.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-profile-specific-configuration">
            
                    
                    25.3、特定 Profile 的配置文件
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-logging">
            
                    
                    26、日志记录
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.4.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-logging-format">
            
                    
                    26.1、日志格式
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.4.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-logging-console-output">
            
                    
                    26.2、控制台输出
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.4.2.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-logging-color-coded-output">
            
                    
                    26.2.1、着色输出
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.4.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-logging-file-output">
            
                    
                    26.3、文件输出
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.4.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-custom-log-levels">
            
                    
                    26.4、日志等级
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.4.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-custom-log-groups">
            
                    
                    26.5、日志组
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.4.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-custom-log-configuration">
            
                    
                    26.6、自定义日志配置
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.4.7" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-logback-extensions">
            
                    
                    26.7、Logback 扩展
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.4.7.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#_profile_specific_configuration">
            
                    
                    26.7.1、特定 Profile 配置
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.4.7.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#_environment_properties">
            
                    
                    26.7.2、环境属性
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-json">
            
                    
                    27、JSON
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.5.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-json-jackson">
            
                    
                    27.1、Jackson
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.5.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-json-gson">
            
                    
                    27.2、Gson
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.5.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-json-json-b">
            
                    
                    27.3、JSON-B
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-developing-web-applications">
            
                    
                    28、开发 Web 应用程序
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.6.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-mvc">
            
                    
                    28.1、Spring Web MVC 框架
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.6.1.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-mvc-auto-configuration">
            
                    
                    28.1.1、Spring MVC 自动配置
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.1.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-mvc-message-converters">
            
                    
                    28.1.2、HttpMessageConverters
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.1.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-message-codes">
            
                    
                    28.1.3、自定义 JSON Serializer 和 Deserializer
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.1.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-mvc-static-content">
            
                    
                    28.1.5、静态内容
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.1.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-mvc-welcome-page">
            
                    
                    28.1.6、欢迎页面
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.1.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-mvc-favicon">
            
                    
                    28.1.7、自定义 Favicon
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.1.7" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-mvc-pathmatch">
            
                    
                    28.1.8、路径匹配与内容协商
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.1.8" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-mvc-web-binding-initializer">
            
                    
                    28.1.9、ConfigurableWebBindingInitializer
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.1.9" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-mvc-template-engines">
            
                    
                    28.1.10、模板引擎
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.1.10" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-error-handling">
            
                    
                    28.1.11、错误处理
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.6.1.10.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-error-handling-custom-error-pages">
            
                    
                    28.1.11.1、自定义错误页面
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.1.10.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-error-handling-mapping-error-pages-without-mvc">
            
                    
                    28.1.11.2、映射到 Spring MVC 之外的错误页面
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.6.1.11" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-hateoas">
            
                    
                    28.1.12、Spring HATEOAS
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.1.12" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-cors">
            
                    
                    28.1.13、CORS 支持
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.6.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webflux">
            
                    
                    28.2、Spring WebFlux 框架
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.6.2.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webflux-auto-configuration">
            
                    
                    28.2.1、Spring WebFlux 自动配置
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.2.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webflux-httpcodecs">
            
                    
                    28.2.2、使用 HttpMessageReader 和 HttpMessageWriter 作为 HTTP 编解码器
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.2.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webflux-static-content">
            
                    
                    28.2.3、静态内容
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.2.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webflux-template-engines">
            
                    
                    28.2.4、模板引擎
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.2.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webflux-error-handling">
            
                    
                    28.2.5、错误处理
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.6.2.5.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webflux-error-handling-custom-error-pages">
            
                    
                    28.2.5.1、自定义错误页面
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.6.2.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webflux-web-filters">
            
                    
                    28.2.6、Web 过滤器
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.6.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jersey">
            
                    
                    28.3、JAX-RS 与 Jersey
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-embedded-container">
            
                    
                    28.4、内嵌 Servlet 容器支持
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.6.4.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-embedded-container-servlets-filters-listeners">
            
                    
                    28.4.1、Servlet、Filter 与 Listener
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.4.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-embedded-container-context-initializer">
            
                    
                    28.4.2、Servlet 上下文初始化
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.6.4.2.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-embedded-container-servlets-filters-listeners-scanning">
            
                    
                    28.4.2.1、扫描 Servlet、Filter 和 Listener
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.6.4.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-embedded-container-application-context">
            
                    
                    28.4.3、ServletWebServerApplicationContext
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.4.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-customizing-embedded-containers">
            
                    
                    28.4.4、自定义内嵌 Servlet 容器
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.6.4.4.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-programmatic-embedded-container-customization">
            
                    
                    28.4.4.1、以编程方式自定义
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.4.4.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-customizing-configurableservletwebserverfactory-directly">
            
                    
                    28.4.4.2、直接自定义 ConfigurableServletWebServerFactory
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.6.4.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jsp-limitations">
            
                    
                    28.4.5、JSP 局限
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.6.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-reactive-server">
            
                    
                    28.5、内嵌响应式服务器支持
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.6.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-reactive-server-resources">
            
                    
                    28.6、响应式服务器资源配置
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.7" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-security">
            
                    
                    29、安全
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.7.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-security-mvc">
            
                    
                    29.1、MVC 安全
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.7.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-security-webflux">
            
                    
                    29.2、WebFlux 安全
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.7.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-security-oauth2">
            
                    
                    29.3、OAuth2
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.7.3.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-security-oauth2-client">
            
                    
                    29.3.1、客户端
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.7.3.1.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-security-oauth2-common-providers">
            
                    
                    OAuth2 客户端注册常见的提供者
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.7.3.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-security-oauth2-server">
            
                    
                    29.3.2、资源服务器
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.7.3.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#_authorization_server">
            
                    
                    29.3.3、授权服务器
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.7.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-security-actuator">
            
                    
                    29.4、Actuator 安全
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.7.4.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-security-csrf">
            
                    
                    29.4.1、跨站请求伪造保护
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.8" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-sql">
            
                    
                    30、使用 SQL 数据库
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.8.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-configure-datasource">
            
                    
                    30.1、配置数据源
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.8.1.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-embedded-database-support">
            
                    
                    30.1.1、内嵌数据库支持
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.8.1.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-connect-to-production-database">
            
                    
                    30.1.2、连接生产数据库
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.8.1.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-connecting-to-a-jndi-datasource">
            
                    
                    30.1.3、连接 JNDI 数据源
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.8.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-using-jdbc-template">
            
                    
                    30.2、使用 JdbcTemplate
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.8.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jpa-and-spring-data">
            
                    
                    30.3、JPA 与 Spring Data JPA
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.8.3.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jpa-and-spring-data">
            
                    
                    30.3.1、实体类
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.8.3.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-data-jpa-repositories">
            
                    
                    30.3.2、Spring Data JPA 资源库
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.8.3.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-creating-and-dropping-jpa-databases">
            
                    
                    30.3.3、创建和删除 JPA 数据库
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.8.3.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jpa-in-web-environment">
            
                    
                    30.3.4、在视图中打开 EntityManager
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.8.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-data-jdbc">
            
                    
                    30.4、Spring Data JDBC
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.8.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-sql-h2-console">
            
                    
                    30.5、使用 H2 的 Web 控制台
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.8.5.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-sql-h2-console-custom-path">
            
                    
                    30.5.1、更改 H2 控制台的路径
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.8.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jooq">
            
                    
                    30.6、使用 jOOQ
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.8.6.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#_code_generation">
            
                    
                    30.6.1、代码生成
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.8.6.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#_using_dslcontext">
            
                    
                    30.6.2、使用 DSLContext
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.8.6.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#_jooq_sql_dialect">
            
                    
                    30.6.3、jOOQ SQL 方言
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.8.6.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#_customizing_jooq">
            
                    
                    30.6.4、自定义 jOOQ
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.9" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-nosql">
            
                    
                    31、使用 NoSQL 技术
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.9.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-redis">
            
                    
                    31.1、Redis
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.9.1.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-connecting-to-redis">
            
                    
                    31.1.1、连接 Redis
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.9.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-mongodb">
            
                    
                    31.2、MongoDB
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.9.2.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-connecting-to-mongodb">
            
                    
                    31.2.1、连接 MongoDB 数据库
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.2.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-mongo-template">
            
                    
                    31.2.2、MongoTemplate
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.2.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-data-mongo-repositories">
            
                    
                    31.2.3、Spring Data MongoDB 资源库
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.2.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-mongo-embedded">
            
                    
                    31.2.4、内嵌 Mongo
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.9.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-neo4j">
            
                    
                    31.3、Neo4j
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.9.3.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-connecting-to-neo4j">
            
                    
                    31.3.1、连接 Neo4j 数据库
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.3.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-connecting-to-neo4j-embedded">
            
                    
                    31.3.2、使用内嵌模式
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.3.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-neo4j-ogm-session">
            
                    
                    31.3.3、Neo4jSession
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.3.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-data-neo4j-repositories">
            
                    
                    31.3.4、Spring Data Neo4j 资源库
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.9.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-gemfire">
            
                    
                    31.4、Gemfire
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-solr">
            
                    
                    31.5、Solr
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.9.5.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-solr">
            
                    
                    31.5.1、连接 Solr
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.5.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-data-solr-repositories">
            
                    
                    31.5.2、Spring Data Solr 资源库
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.9.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-elasticsearch">
            
                    
                    31.6、Elasticsearch
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.9.6.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-connecting-to-elasticsearch-rest">
            
                    
                    31.6.1、使用 REST 客户端连接 Elasticsearch
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.6.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-connecting-to-elasticsearch-jest">
            
                    
                    31.6.2、使用 Jest 连接 Elasticsearch
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.6.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-connecting-to-elasticsearch-spring-data">
            
                    
                    31.6.3、使用 Spring Data 连接 Elasticsearch
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.6.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-data-elasticsearch-repositories">
            
                    
                    31.6.4、Spring Data Elasticsearch 资源库
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.9.7" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-cassandra">
            
                    
                    31.7、Cassandra
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.9.7.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-connecting-to-cassandra">
            
                    
                    31.7.1、连接 Cassandra
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.7.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-data-cassandra-repositories">
            
                    
                    31.7.2、Spring Data Cassandra 资源库
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.9.8" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-couchbase">
            
                    
                    31.8、Couchbase
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.9.8.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-connecting-to-couchbase">
            
                    
                    31.8.1、连接 Couchbase
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.8.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spring-data-couchbase-repositories">
            
                    
                    31.8.2、Spring Data Couchbase 资源库
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.9.9" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-ldap">
            
                    
                    31.9、LDAP
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.9.9.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-ldap-connecting">
            
                    
                    31.9.1、连接 LDAP 服务器
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.9.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-ldap-spring-data-repositories">
            
                    
                    31.9.2、Spring Data LDAP 资源库
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.9.9.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-ldap-embedded">
            
                    
                    31.9.3、内嵌内存式 LDAP 服务器
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.9.10" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-influxdb">
            
                    
                    31.10、InfluxDB
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.9.10.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-connecting-to-influxdb">
            
                    
                    31.10.1、连接 InfluxDB
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.10" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-caching">
            
                    
                    32、缓存
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.10.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-caching-provider">
            
                    
                    32.1、支持的缓存提供者
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.10.1.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-caching-provider-generic">
            
                    
                    32.1.1、Generic
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.10.1.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-caching-provider-jcache">
            
                    
                    32.1.2、JCache (JSR-107)
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.10.1.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-caching-provider-ehcache2">
            
                    
                    32.1.3、EhCache 2.x
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.10.1.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-caching-provider-hazelcast">
            
                    
                    32.1.4、Hazelcast
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.10.1.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-caching-provider-infinispan">
            
                    
                    32.1.5、Infinispan
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.10.1.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-caching-provider-couchbase">
            
                    
                    32.1.6、Couchbase
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.10.1.7" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-caching-provider-redis">
            
                    
                    32.1.7、Redis
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.10.1.8" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-caching-provider-caffeine">
            
                    
                    32.1.8、Caffeine
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.10.1.9" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-caching-provider-simple">
            
                    
                    32.1.9、Simple
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.10.1.10" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-caching-provider-none">
            
                    
                    32.1.10、None
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.11" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-messaging">
            
                    
                    33、消息传递
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.11.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jms">
            
                    
                    33.1、JMS
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.11.1.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-activemq">
            
                    
                    33.1.1、ActiveMQ 支持
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.11.1.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-artemis">
            
                    
                    33.1.2、Artemis 支持
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.11.1.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jms-jndi">
            
                    
                    33.1.3、使用 JNDI ConnectionFactory
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.11.1.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-using-jms-sending">
            
                    
                    33.1.4、发送消息
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.11.1.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-using-jms-receiving">
            
                    
                    33.1.5、接收消息
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.11.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-amqp">
            
                    
                    33.2、AMQP
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.11.2.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-rabbitmq">
            
                    
                    33.2.1、RabbitMQ 支持
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.11.2.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-using-amqp-sending">
            
                    
                    33.2.2、发送消息
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.11.2.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-using-amqp-receiving">
            
                    
                    33.2.3、接收消息
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.11.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kafka">
            
                    
                    33.3、Apache Kafka 支持
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.11.3.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kafka-sending-a-message">
            
                    
                    33.3.1、发送消息
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.11.3.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kafka-receiving-a-message">
            
                    
                    33.3.2、接收消息
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.11.3.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kafka-streams">
            
                    
                    33.3.3、Kafka Stream
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.11.3.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kafka-extra-props">
            
                    
                    33.3.4、其他 Kafka 属性
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.12" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-resttemplate">
            
                    
                    34、使用 RestTemplate 调用 REST 服务
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.12.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-resttemplate-customization">
            
                    
                    34.1、自定义 RestTemplate
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.12.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-resttemplate">
            
                    
                    34、使用 RestTemplate 调用 REST 服务
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.13" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webclient">
            
                    
                    35、使用 WebClient 调用 REST 服务
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.13.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webclient-runtime">
            
                    
                    35.1、WebClient 运行时
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.13.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webclient-customization">
            
                    
                    35.2、自定义 WebClient
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.14" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-validation">
            
                    
                    36、验证
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.15" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-email">
            
                    
                    37、发送邮件
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.16" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jta">
            
                    
                    38、JTA 分布式事务
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.16.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jta-atomikos">
            
                    
                    38.1、使用 Atomikos 事务管理器
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.16.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jta-bitronix">
            
                    
                    38.2、使用 Bitronix 事务管理器
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.16.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jta-javaee">
            
                    
                    38.3、使用 Java EE 管理的事务管理器
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.16.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jta-mixed-jms">
            
                    
                    38.4、混合使用 XA 与非 XA JMS 连接
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.17" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-hazelcast">
            
                    
                    39、Hazelcast
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.18" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-quartz">
            
                    
                    40、Quartz 调度器
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.19" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-task-execution-scheduling">
            
                    
                    41、任务执行与调度
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.20" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-integration">
            
                    
                    42、Spring Integration
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.21" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-session">
            
                    
                    43、Spring Session
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.22" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-jmx">
            
                    
                    44、通过 JMX 监控和管理
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.23" >
            
                <span>
            
                    
                    45、测试
            
                </span>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.24" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-websockets">
            
                    
                    46、WebSocket
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.25" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webservices">
            
                    
                    47、Web Service
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.25.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-webservices-template">
            
                    
                    47.1、使用 WebServiceTemplate 调用 Web Service
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.26" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-developing-auto-configuration">
            
                    
                    49、创建自己的自动配置
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.26.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-understanding-auto-configured-beans">
            
                    
                    49.1、理解自定配置 Bean
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.26.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-locating-auto-configuration-candidates">
            
                    
                    49.2、找到候选的自动配置
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.26.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-condition-annotations">
            
                    
                    49.3、条件注解
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.26.3.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-class-conditions">
            
                    
                    49.3.1、类条件
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.26.3.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-bean-conditions">
            
                    
                    49.3.2、Bean 条件
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.26.3.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-property-conditions">
            
                    
                    49.3.3、属性条件
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.26.3.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-resource-conditions">
            
                    
                    49.3.4、资源条件
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.26.3.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-web-application-conditions">
            
                    
                    49.3.5、Web 应用程序条件
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.26.3.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-spel-conditions">
            
                    
                    49.3.6、SpEL 表达式条件
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.26.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-test-autoconfig">
            
                    
                    49.4、测试自动配置
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.26.4.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#_simulating_a_web_context">
            
                    
                    49.4.1、模拟一个 Web 上下文
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.26.4.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#_overriding_the_classpath">
            
                    
                    49.4.2、覆盖 Classpath
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.26.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-custom-starter">
            
                    
                    49.5、创建自己的 Starter
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.26.5.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-custom-starter-naming">
            
                    
                    49.5.1、命名
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.26.5.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-custom-starter-module-autoconfigure">
            
                    
                    49.5.2、autoconfigure 模块
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.26.5.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-custom-starter-module-starter">
            
                    
                    49.5.3、Starter 模块
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.27" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kotlin">
            
                    
                    50、Kotlin 支持
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.27.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kotlin-requirements">
            
                    
                    50.1、要求
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.27.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kotlin-null-safety">
            
                    
                    50.2、Null 安全
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.27.3" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kotlin-api">
            
                    
                    50.3、Kotlin API
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.27.3.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kotlin-api-runapplication">
            
                    
                    50.3.1、runApplication
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.27.3.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kotlin-api-extensions">
            
                    
                    50.3.2、扩展
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.27.4" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kotlin-dependency-management">
            
                    
                    50.4、依赖管理
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.27.5" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kotlin-configuration-properties">
            
                    
                    50.5、@ConfigurationProperties
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.27.6" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kotlin-testing">
            
                    
                    50.6、测试
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.27.7" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kotlin-resources">
            
                    
                    50.7、资源
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.6.27.7.1" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kotlin-resources-further-reading">
            
                    
                    50.7.1、进阶阅读
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.6.27.7.2" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-kotlin-resources-examples">
            
                    
                    50.7.2、示例
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.6.28" data-path="spring-boot-features.html">
            
                <a href="spring-boot-features.html#boot-features-whats-next">
            
                    
                    51、下一步
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready">
            
                    
                    五、Spring Boot Actuator: 生产就绪功能
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-enabling">
            
                    
                    52、启用生产就绪功能
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints">
            
                    
                    53、端点
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.2.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints-enabling-endpoints">
            
                    
                    53.1、启用端点
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.2" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints-exposing-endpoints">
            
                    
                    53.2、暴露端点
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.3" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints-security">
            
                    
                    53.3、保护 HTTP 端点
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.4" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints-caching">
            
                    
                    53.4、配置端点
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.5" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints-hypermedia">
            
                    
                    53.5、Actuator Web 端点超媒体
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.6" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints-cors">
            
                    
                    53.6、跨域支持
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.7" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints-custom">
            
                    
                    53.7、实现自定义端点
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.2.7.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints-custom-input">
            
                    
                    53.7.1、接收输入
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.7.2" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints-custom-web">
            
                    
                    53.7.2、自定义 Web 端点
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.7.3" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints-custom-servlet">
            
                    
                    53.7.3、Servlet 端点
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.7.4" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints-custom-controller">
            
                    
                    53.7.4、控制器端点
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.2.8" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-endpoints-custom-controller">
            
                    
                    53.8、健康信息
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.2.8.1" data-path="production-ready.html">
            
                <a href="production-ready.html#_auto_configured_healthindicators">
            
                    
                    53.8.1、自动配置的 HealthIndicator
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.8.2" data-path="production-ready.html">
            
                <a href="production-ready.html#_writing_custom_healthindicators">
            
                    
                    53.8.2、编写自定义 HealthIndicator
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.8.3" data-path="production-ready.html">
            
                <a href="production-ready.html#reactive-health-indicators">
            
                    
                    53.8.3、响应式健康指示器
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.8.4" data-path="production-ready.html">
            
                <a href="production-ready.html#_auto_configured_reactivehealthindicators">
            
                    
                    53.8.4、自动配置的 ReactiveHealthIndicator
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.2.9" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-application-info">
            
                    
                    53.9、应用程序信息
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.2.9.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-application-info">
            
                    
                    53.9.1、自动配置的 InfoContributor
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.9.2" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-application-info-env">
            
                    
                    53.9.2、自定义应用程序信息
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.9.3" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-application-info-git">
            
                    
                    53.9.3、Git 提交信息
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.9.4" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-application-info-build">
            
                    
                    53.9.4、构建信息
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.2.9.5" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-application-info-build">
            
                    
                    53.9.5、编写自定义 InfoContributor
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.3" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-monitoring">
            
                    
                    54、通过 HTTP 监控和管理
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.3.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-customizing-management-server-context-path">
            
                    
                    54.1、自定义 Management 端点路径
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.3.2" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-customizing-management-server-port">
            
                    
                    54.2、自定义 Management 服务器端口
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.3.3" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-management-specific-ssl">
            
                    
                    54.3、配置 Management 的 SSL
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.3.4" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-customizing-management-server-address">
            
                    
                    54.4、配置 Management 服务器地址
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.3.5" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-disabling-http-endpoints">
            
                    
                    54.5、禁用 HTTP 端点
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.4" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-jmx">
            
                    
                    55、通过 JMX 监控和管理
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.4.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-custom-mbean-names">
            
                    
                    55.1、自定义 MBean 名称
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.4.2" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-disable-jmx-endpoints">
            
                    
                    55.2、禁用 JMX 端点
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.4.3" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-jolokia">
            
                    
                    55.3、通过 HTTP 使用 Jolokia 访问 JMX
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.4.3.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-customizing-jolokia">
            
                    
                    55.3.1、自定义 Jolokia
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.4.3.2" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-disabling-jolokia">
            
                    
                    55.3.2、禁用 Jolokia
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.5" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-loggers">
            
                    
                    56、日志记录器
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.5.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-logger-configuration">
            
                    
                    56.1、配置一个日志记录器
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.6" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics">
            
                    
                    57、指标
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.6.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-getting-started">
            
                    
                    57.1、入门
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export">
            
                    
                    57.2、支持的监控系统
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.6.2.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-appoptics">
            
                    
                    57.2.1、AppOptics
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.2" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-atlas">
            
                    
                    57.2.2、Atlas
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.3" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-datadog">
            
                    
                    57.2.3、Datadog
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.4" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-dynatrace">
            
                    
                    57.2.4、Dynatrace
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.5" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-elastic">
            
                    
                    57.2.5、Elastic
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.6" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-ganglia">
            
                    
                    57.2.6、Ganglia
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.7" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-graphite">
            
                    
                    57.2.7、Graphite
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.8" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-humio">
            
                    
                    57.2.8、Humio
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.9" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-influx">
            
                    
                    57.2.9、Influx
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.10" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-jmx">
            
                    
                    57.2.10、JMX
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.11" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-kairos">
            
                    
                    57.2.11、KairosDB
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.12" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-newrelic">
            
                    
                    57.2.12、New Relic
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.13" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-prometheus">
            
                    
                    57.2.13、Prometheus
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.14" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-signalfx">
            
                    
                    57.2.14、SignalFx
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.15" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-simple">
            
                    
                    57.2.15、Simple
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.16" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-statsd">
            
                    
                    57.2.16、StatsD
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.2.17" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-export-wavefront">
            
                    
                    57.2.17、Wavefront
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.6.3" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-meter">
            
                    
                    57.3、支持的指标
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.6.3.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-spring-mvc">
            
                    
                    57.3.1、Spring MVC 指标
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.3.2" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-web-flux">
            
                    
                    57.3.2、Spring WebFlux 指标
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.3.3" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-jersey-server">
            
                    
                    57.3.3、Jersey Server 指标
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.3.4" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-http-clients">
            
                    
                    57.3.4、HTTP Client 指标
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.3.5" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-cache">
            
                    
                    57.3.5、Cache 指标
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.3.6" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-jdbc">
            
                    
                    57.3.6、数据源指标
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.3.7" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-hibernate">
            
                    
                    57.3.7、Hibernate 指标
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.3.8" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-rabbitmq">
            
                    
                    57.3.8、RabbitMQ 指标
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.6.4" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-custom">
            
                    
                    57.4、注册自定义指标
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.5" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-per-meter-properties">
            
                    
                    57.5、自定义单独指标
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.6.5.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-common-tags">
            
                    
                    57.5.1、自定义标签
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.6.5.2" data-path="production-ready.html">
            
                <a href="production-ready.html#_per_meter_properties">
            
                    
                    57.5.2、Per-meter 属性
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.6.6" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-metrics-endpoint">
            
                    
                    57.6、指标端点
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.7" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-auditing">
            
                    
                    58、审计
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.8" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-http-tracing">
            
                    
                    59、HTTP 追踪
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.8.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-http-tracing-custom">
            
                    
                    59.1、自定义 HTTP 追踪
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.9" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-process-monitoring">
            
                    
                    60、进程监控
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.9.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-process-monitoring-configuration">
            
                    
                    60.1、扩展配置
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.9.2" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-process-monitoring-configuration">
            
                    
                    60.2、编程方式
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.10" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-cloudfoundry">
            
                    
                    61、Cloud Foundry 支持
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.7.10.1" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-cloudfoundry-disable">
            
                    
                    61.1、禁用 Cloud Foundry Actuator 扩展支持
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.10.2" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-cloudfoundry-ssl">
            
                    
                    61.2、Cloud Foundry 自签名证书
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.7.10.3" data-path="production-ready.html">
            
                <a href="production-ready.html#_custom_context_path">
            
                    
                    61.3、自定义上下文路径
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.7.11" data-path="production-ready.html">
            
                <a href="production-ready.html#production-ready-auditing">
            
                    
                    62、下一步
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.8" data-path="deployment.html">
            
                <a href="deployment.html">
            
                    
                    六、部署 Spring Boot 应用程序
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.8.1" >
            
                <span>
            
                    
                    63、部署到云端
            
                </span>
            

            
        </li>
    
        <li class="chapter " data-level="1.8.2" >
            
                <span>
            
                    
                    64、安装 Spring Boot 应用程序
            
                </span>
            

            
        </li>
    
        <li class="chapter " data-level="1.8.3" >
            
                <span>
            
                    
                    65、下一步
            
                </span>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.9" >
            
                <span>
            
                    
                    七、Spring Boot CLI
            
                </span>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.9.1" >
            
                <span>
            
                    
                    66、安装 CLI
            
                </span>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.2" >
            
                <span>
            
                    
                    67、使用 CLI
            
                </span>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.3" >
            
                <span>
            
                    
                    68、使用 Groovy Beans DSL 部署应用程序
            
                </span>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.4" >
            
                <span>
            
                    
                    69、使用  配置 CLI
            
                </span>
            

            
        </li>
    
        <li class="chapter " data-level="1.9.5" >
            
                <span>
            
                    
                    70、下一步
            
                </span>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="1.10" >
            
                <span>
            
                    
                    八、构建工具插件
            
                </span>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="1.10.1" >
            
                <span>
            
                    
                    71、Spring Boot Maven 插件
            
                </span>
            

            
        </li>
    
        <li class="chapter " data-level="1.10.2" >
            
                <span>
            
                    
                    72、Spring Boot Gradle 插件
            
                </span>
            

            
        </li>
    
        <li class="chapter " data-level="1.10.3" >
            
                <span>
            
                    
                    73、Spring Boot AntLib 模块
            
                </span>
            

            
        </li>
    
        <li class="chapter " data-level="1.10.4" >
            
                <span>
            
                    
                    74、支持其他构建系统
            
                </span>
            

            
        </li>
    
        <li class="chapter " data-level="1.10.5" >
            
                <span>
            
                    
                    75、下一步
            
                </span>
            

            
        </li>
    

            </ul>
            
        </li>
    

    

    <li class="divider"></li>

    <li>
        <a href="https://www.gitbook.com" target="blank" class="gitbook-link">
            本书使用 GitBook 发布
        </a>
    </li>
</ul>


                </nav>
            
        
    </div>

    <div class="book-body">
        
            <div class="body-inner">
                
                    

<div class="book-header" role="navigation">
    

    <!-- Title -->
    <h1>
        <i class="fa fa-circle-o-notch fa-spin"></i>
        <a href=".." >四、Spring Boot 特性</a>
    </h1>
</div>




                    <div class="page-wrapper" tabindex="-1" role="main">
                        <div class="page-inner">
                            
<div class="search-plus" id="book-search-results">
    <div class="search-noresults">
    
                                <section class="normal markdown-section">
                                
                                <p><a id="boot-features"></a></p>
<h1 id="&#x56DB;&#x3001;spring-boot-&#x7279;&#x6027;">&#x56DB;&#x3001;Spring Boot &#x7279;&#x6027;</h1>
<p>&#x672C;&#x90E8;&#x5206;&#x5C06;&#x4ECB;&#x7ECD; Spring Boot &#x76F8;&#x5173;&#x7684;&#x7EC6;&#x8282;&#x5185;&#x5BB9;&#x3002;&#x5728;&#x8FD9;&#x91CC;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5B66;&#x4E60;&#x5230;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x4F7F;&#x7528;&#x548C;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x4E3B;&#x8981;&#x529F;&#x80FD;&#x3002;&#x60A8;&#x5982;&#x679C;&#x8FD8;&#x6CA1;&#x6709;&#x505A;&#x597D;&#x5145;&#x5206;&#x51C6;&#x5907;&#xFF0C;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x9605;&#x8BFB;<a href="#getting-started">&#x7B2C;&#x4E8C;&#x90E8;&#x5206;&#xFF1A;&#x5165;&#x95E8;</a>&#x548C;<a href="#using-boot">&#x7B2C;&#x4E09;&#x90E8;&#x5206;&#xFF1A;&#x4F7F;&#x7528; Spring Boot</a>&#xFF0C;&#x4EE5;&#x4FBF;&#x6253;&#x4E0B;&#x524D;&#x671F;&#x57FA;&#x7840;&#x3002;</p>
<p><a id="boot-features-spring-application"></a></p>
<h2 id="23&#x3001;springapplication">23&#x3001;SpringApplication</h2>
<p><code>SpringApplication</code> &#x7C7B;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x79CD;&#x53EF;&#x901A;&#x8FC7;&#x8FD0;&#x884C; <code>main()</code> &#x65B9;&#x6CD5;&#x6765;&#x542F;&#x52A8; Spring &#x5E94;&#x7528;&#x7684;&#x7B80;&#x5355;&#x65B9;&#x5F0F;&#x3002;&#x591A;&#x6570;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x60A8;&#x53EA;&#x9700;&#x8981;&#x59D4;&#x6258;&#x7ED9;&#x9759;&#x6001;&#x7684; <code>SpringApplication.run</code> &#x65B9;&#x6CD5;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">MySpringConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>&#x5F53;&#x5E94;&#x7528;&#x542F;&#x52A8;&#x65F6;&#xFF0C;&#x60A8;&#x5E94;&#x8BE5;&#x4F1A;&#x770B;&#x5230;&#x7C7B;&#x4F3C;&#x4EE5;&#x4E0B;&#x7684;&#x5185;&#x5BB9;&#x8F93;&#x51FA;&#xFF1A;</p>
<pre class="language-"><code>  .   ____          _            __ _ _
 /\\ / ___&apos;_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | &apos;_ | &apos;_| | &apos;_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  &apos;  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::   v2.1.1.RELEASE

2013-07-31 00:08:16.117  INFO 56603 --- [           main] o.s.b.s.app.SampleApplication            : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
2013-07-31 00:08:16.166  INFO 56603 --- [           main] ationConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
2014-03-04 13:09:54.912  INFO 41370 --- [           main] .t.TomcatServletWebServerFactory : Server initialized with port: 8080
2014-03-04 13:09:56.501  INFO 41370 --- [           main] o.s.b.s.app.SampleApplication            : Started SampleApplication in 2.992 seconds (JVM running for 3.658)
</code></pre><p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5C06;&#x663E;&#x793A; <code>INFO</code> &#x7EA7;&#x522B;&#x7684;&#x65E5;&#x5FD7;&#x4FE1;&#x606F;&#xFF0C;&#x5305;&#x62EC;&#x4E00;&#x4E9B;&#x5E94;&#x7528;&#x542F;&#x52A8;&#x76F8;&#x5173;&#x4FE1;&#x606F;&#x3002;&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x4FEE;&#x6539; <code>INFO</code> &#x65E5;&#x5FD7;&#x7EA7;&#x522B;&#xFF0C;&#x8BF7;&#x53C2;&#x8003; <a href="#boot-features-custom-log-levels">26.4 &#x90E8;&#x5206;&#xFF1A;&#x65E5;&#x5FD7;&#x7B49;&#x7EA7;</a>&#x3002;</p>
<p><a id="boot-features-startup-failure"></a></p>
<h3 id="231&#x3001;&#x542F;&#x52A8;&#x5931;&#x8D25;">23.1&#x3001;&#x542F;&#x52A8;&#x5931;&#x8D25;</h3>
<p>&#x5982;&#x679C;&#x60A8;&#x7684;&#x5E94;&#x7528;&#x65E0;&#x6CD5;&#x542F;&#x52A8;&#xFF0C;&#x6CE8;&#x518C;&#x7684; <code>FailureAnalyzers</code> &#x53EF;&#x80FD;&#x4F1A;&#x63D0;&#x4F9B;&#x6709;&#x76F8;&#x5173;&#x7684;&#x9519;&#x8BEF;&#x4FE1;&#x606F;&#x548C;&#x89E3;&#x51B3;&#x95EE;&#x9898;&#x7684;&#x5177;&#x4F53;&#x65B9;&#x6CD5;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x5728;&#x5DF2;&#x7ECF;&#x88AB;&#x5360;&#x7528;&#x7684; <code>8080</code> &#x7AEF;&#x53E3;&#x4E0A;&#x542F;&#x52A8;&#x4E86;&#x4E00;&#x4E2A; web &#x5E94;&#x7528;&#xFF0C;&#x4F1A;&#x770B;&#x5230;&#x7C7B;&#x4F3C;&#x4EE5;&#x4E0B;&#x7684;&#x9519;&#x8BEF;&#x4FE1;&#x606F;&#xFF1A;</p>
<pre class="language-"><code>***************************
APPLICATION FAILED TO START
***************************

Description:

Embedded servlet container failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that&apos;s listening on port 8080 or configure this application to listen on another port.
</code></pre><p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x8BB8;&#x591A;&#x7684; <code>FailureAnalyzer</code> &#x5B9E;&#x73B0;&#xFF0C;&#x60A8;&#x4E5F;&#x53EF;&#x4EE5;<a href="#howto-failure-analyzer">&#x6DFB;&#x52A0;&#x81EA;&#x5DF1;&#x7684;&#x5B9E;&#x73B0;</a>&#x3002;</p>
</blockquote>
<p>&#x5982;&#x679C;&#x6CA1;&#x6709;&#x5931;&#x8D25;&#x5206;&#x6790;&#x5668;&#x80FD;&#x591F;&#x5904;&#x7406;&#x7684;&#x5F02;&#x5E38;&#xFF0C;&#x60A8;&#x4ECD;&#x7136;&#x53EF;&#x4EE5;&#x663E;&#x793A;&#x5B8C;&#x6574;&#x7684;&#x6761;&#x4EF6;&#x62A5;&#x544A;&#x4EE5;&#x4FBF;&#x66F4;&#x597D;&#x5730;&#x4E86;&#x89E3;&#x51FA;&#x73B0;&#x7684;&#x95EE;&#x9898;&#x3002;&#x4E3A;&#x6B64;&#xFF0C;&#x60A8;&#x9700;&#x8981;&#x9488;&#x5BF9; <code>org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener</code> <a href="#boot-features-external-config">&#x542F;&#x7528; <code>debug</code> &#x5C5E;&#x6027;</a>&#x6216;&#x8005;<a href="#boot-features-custom-log-levels">&#x5F00;&#x542F; <code>DEBUG</code> &#x65E5;&#x5FD7;</a>&#x3002;</p>
<p>&#x4F8B;&#x5982;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528; <code>java -jar</code> &#x8FD0;&#x884C;&#x5E94;&#x7528;&#xFF0C;&#x53EF;&#x4EE5;&#x6309;&#x4EE5;&#x4E0B;&#x65B9;&#x5F0F;&#x542F;&#x7528; <code>debug</code> &#x5C5E;&#x6027;&#xFF1A;</p>
<pre class="language-"><code>$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug
</code></pre><p><a id="boot-features-banner"></a></p>
<h3 id="232&#x3001;&#x81EA;&#x5B9A;&#x4E49;-banner">23.2&#x3001;&#x81EA;&#x5B9A;&#x4E49; banner</h3>
<p>&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5728; classpath &#x4E0B;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A; <code>banner.txt</code> &#x6587;&#x4EF6;&#xFF0C;&#x6216;&#x8005;&#x5C06; <code>spring.banner.location</code> &#x5C5E;&#x6027;&#x6307;&#x5411;&#x8BE5;&#x6587;&#x4EF6;&#x7684;&#x4F4D;&#x7F6E;&#x6765;&#x66F4;&#x6539;&#x542F;&#x52A8;&#x65F6;&#x6253;&#x5370;&#x7684; banner&#x3002;&#x5982;&#x679C;&#x6587;&#x4EF6;&#x91C7;&#x7528;&#x4E86;&#x975E; UTF-8 &#x7F16;&#x7801;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x8BBE;&#x7F6E; <code>spring.banner.charset</code> &#x6765;&#x89E3;&#x51B3;&#x3002;&#x9664;&#x4E86;&#x6587;&#x672C;&#x6587;&#x4EF6;&#xFF0C;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x5C06; <code>banner.gif</code>&#x3001;<code>banner.jpg</code> &#x6216;&#x8005; <code>banner.png</code> &#x56FE;&#x7247;&#x6587;&#x4EF6;&#x6DFB;&#x52A0;&#x5230; classpath &#x4E0B;&#xFF0C;&#x6216;&#x8005;&#x8BBE;&#x7F6E; <code>spring.banner.image.location</code> &#x5C5E;&#x6027;&#x3002;&#x6307;&#x5B9A;&#x7684;&#x56FE;&#x7247;&#x5C06;&#x4F1A;&#x88AB;&#x8F6C;&#x6362;&#x6210; ASCII &#x5F62;&#x5F0F;&#x5E76;&#x6253;&#x5370;&#x5728; banner &#x6587;&#x672C;&#x4E0A;&#x65B9;&#x3002;</p>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>banner.txt</code> &#x6587;&#x4EF6;&#x4E2D;&#x4F7F;&#x7528;&#x4EE5;&#x4E0B;&#x5360;&#x4F4D;&#x7B26;&#xFF1A;</p>
<table>
<thead>
<tr>
<th>&#x53D8;&#x91CF;</th>
<th>&#x63CF;&#x8FF0;</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>${application.version}</code></td>
<td>&#x60A8;&#x7684;&#x5E94;&#x7528;&#x7248;&#x672C;&#x53F7;&#xFF0C;&#x58F0;&#x660E;&#x5728; <code>MANIFEST.MF</code> &#x4E2D;&#x3002;&#x4F8B;&#x5982;&#xFF0C;<code>Implementation-Version: 1.0</code> &#x5C06;&#x88AB;&#x6253;&#x5370;&#x4E3A; <code>1.0</code>&#x3002;</td>
</tr>
<tr>
<td><code>${application.formatted-version}</code></td>
<td>&#x60A8;&#x7684;&#x5E94;&#x7528;&#x7248;&#x672C;&#x53F7;&#xFF0C;&#x58F0;&#x660E;&#x5728; <code>MANIFEST.MF</code> &#x4E2D;&#xFF0C;&#x683C;&#x5F0F;&#x5316;&#x4E4B;&#x540E;&#x6253;&#x5370;&#xFF08;&#x7528;&#x62EC;&#x53F7;&#x62EC;&#x8D77;&#x6765;&#xFF0C;&#x4EE5; <code>v</code> &#x4E3A;&#x524D;&#x7F00;&#xFF09;&#xFF0C;&#x4F8B;&#x5982; (<code>v1.0</code>)&#x3002;</td>
</tr>
<tr>
<td><code>${spring-boot.version}</code></td>
<td>&#x60A8;&#x4F7F;&#x7528;&#x7684; Spring Boot &#x7248;&#x672C;&#x3002;&#x4F8B;&#x5982; <code>2.1.1.RELEASE.</code>&#x3002;</td>
</tr>
<tr>
<td><code>${spring-boot.formatted-version}</code></td>
<td>&#x60A8;&#x4F7F;&#x7528;&#x7684; Spring Boot &#x7248;&#x672C;&#x683C;&#x5F0F;&#x5316;&#x4E4B;&#x540E;&#x663E;&#x793A;&#xFF08;&#x7528;&#x62EC;&#x53F7;&#x62EC;&#x8D77;&#x6765;&#xFF0C;&#x4EE5; <code>v</code> &#x4E3A;&#x524D;&#x7F00;&#xFF09;&#x3002;&#x4F8B;&#x5982; (<code>v2.1.1.RELEASE</code>)&#x3002;</td>
</tr>
<tr>
<td><code>${Ansi.NAME}</code>&#xFF08;&#x6216; <code>${AnsiColor.NAME}</code>&#x3001;<br><code>${AnsiBackground.NAME}</code>&#x3001;<br><code>${AnsiStyle.NAME}</code>&#xFF09;</td>
<td>&#x5176;&#x4E2D; <code>NAME</code> &#x662F; ANSI &#x8F6C;&#x4E49;&#x7801;&#x7684;&#x540D;&#x79F0;&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/ansi/AnsiPropertySource.java" target="_blank">AnsiPropertySource</a>&#x3002;</td>
</tr>
<tr>
<td><code>${application.title}</code></td>
<td>&#x60A8;&#x7684;&#x5E94;&#x7528;&#x6807;&#x9898;&#xFF0C;&#x58F0;&#x660E;&#x5728; <code>MANIFEST.MF</code> &#x4E2D;&#xFF0C;&#x4F8B;&#x5982; <code>Implementation-Title: MyApp</code> &#x6253;&#x5370;&#x4E3A; <code>MyApp</code>&#x3002;</td>
</tr>
</tbody>
</table>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x60F3;&#x4EE5;&#x7F16;&#x7A0B;&#x7684;&#x65B9;&#x5F0F;&#x751F;&#x6210; banner&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>SpringApplication.setBanner(&#x200B;...)</code> &#x65B9;&#x6CD5;&#x3002;&#x4F7F;&#x7528; <code>org.springframework.boot.Banner</code> &#x63A5;&#x53E3;&#x5E76;&#x5B9E;&#x73B0;&#x81EA;&#x5DF1;&#x7684; <code>printBanner()</code> &#x65B9;&#x6CD5;&#x3002;</p>
</blockquote>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.main.banner-mode</code> &#x5C5E;&#x6027;&#x6765;&#x786E;&#x5B9A;&#x662F;&#x5426;&#x5FC5;&#x987B;&#x5728; <code>System.out</code>&#xFF08;<code>console</code>&#xFF09;&#x4E0A;&#x6253;&#x5370; banner&#xFF0C;&#x8FD8;&#x662F;&#x4F7F;&#x7528;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5668;&#xFF08;<code>log</code>&#xFF09;&#x6216;&#x8005;&#x90FD;&#x4E0D;&#x6253;&#x5370;&#xFF08;<code>off</code>&#xFF09;&#x3002;</p>
<p>&#x6253;&#x5370;&#x7684; banner &#x88AB;&#x6CE8;&#x518C;&#x540D;&#x4E3A; <code>springBootBanner</code> &#x7684;&#x5355;&#x4F8B; bean&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>YAML &#x5C06; <code>off</code> &#x6620;&#x5C04;&#x4E3A; <code>false</code>&#xFF0C;&#x56E0;&#x6B64;&#x5982;&#x679C;&#x8981;&#x7981;&#x7528;&#x5E94;&#x7528;&#x7A0B;&#x5E8F; banner&#xFF0C;&#x8BF7;&#x786E;&#x4FDD;&#x5C5E;&#x6027;&#x6DFB;&#x52A0;&#x5F15;&#x53F7;&#x3002;</p>
</blockquote>
<pre class="language-"><code class="lang-yaml"><span class="token key atrule">spring</span><span class="token punctuation">:</span>
    <span class="token key atrule">main</span><span class="token punctuation">:</span>
        <span class="token key atrule">banner-mode</span><span class="token punctuation">:</span> <span class="token string">&quot;off&quot;</span>
</code></pre>
<p><a id="boot-features-customizing-spring-application"></a></p>
<h3 id="233&#x3001;&#x81EA;&#x5B9A;&#x4E49;-springapplication">23.3&#x3001;&#x81EA;&#x5B9A;&#x4E49; SpringApplication</h3>
<p>&#x5982;&#x679C; <code>SpringApplication</code> &#x7684;&#x9ED8;&#x8BA4;&#x8BBE;&#x7F6E;&#x4E0D;&#x7B26;&#x5408;&#x60A8;&#x7684;&#x60F3;&#x6CD5;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x521B;&#x5EFA;&#x672C;&#x5730;&#x5B9E;&#x4F8B;&#x8FDB;&#x884C;&#x5B9A;&#x5236;&#x5316;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x8981;&#x5173;&#x95ED; banner&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x8FD9;&#x6837;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token class-name">SpringApplication</span> app <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SpringApplication</span><span class="token punctuation">(</span><span class="token class-name">MySpringConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    app<span class="token punctuation">.</span><span class="token function">setBannerMode</span><span class="token punctuation">(</span><span class="token class-name">Banner</span><span class="token punctuation">.</span><span class="token class-name">Mode</span><span class="token punctuation">.</span>OFF<span class="token punctuation">)</span><span class="token punctuation">;</span>
    app<span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x4F20;&#x5165; <code>SpringApplication</code> &#x7684;&#x6784;&#x9020;&#x53C2;&#x6570;&#x662F; spring bean &#x7684;&#x914D;&#x7F6E;&#x6E90;&#x3002;&#x5927;&#x591A;&#x60C5;&#x51B5;&#x4E0B;&#x662F;&#x5F15;&#x7528; <code>@Configuration</code> &#x7C7B;&#xFF0C;&#x4F46;&#x60A8;&#x4E5F;&#x53EF;&#x4EE5;&#x5F15;&#x7528; XML &#x914D;&#x7F6E;&#x6216;&#x8005;&#x88AB;&#x626B;&#x63CF;&#x7684;&#x5305;&#x3002;</p>
</blockquote>
<p>&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>application.properties</code> &#x6587;&#x4EF6;&#x914D;&#x7F6E; <code>SpringApplication</code>&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x89C1;<a href="#boot-features-external-config">&#x7B2C; 24 &#x7AE0;&#xFF1A;&#x5916;&#x90E8;&#x5316;&#x914D;&#x7F6E;</a>&#x3002;</p>
<p>&#x5173;&#x4E8E;&#x914D;&#x7F6E;&#x9009;&#x9879;&#x7684;&#x5B8C;&#x6574;&#x5217;&#x8868;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/api/org/springframework/boot/SpringApplication.html" target="_blank">SpringApplication Javadoc</a>&#x3002;</p>
<p><a id="boot-features-customizing-spring-application"></a></p>
<h3 id="234&#x3001;fluent-builder-api">23.4&#x3001;Fluent Builder API</h3>
<p>&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x6784;&#x5EFA;&#x4E00;&#x4E2A;&#x6709;&#x5C42;&#x7EA7;&#x5173;&#x7CFB;&#x7684; <code>ApplicationContext</code>&#xFF08;&#x5177;&#x6709;&#x7236;/&#x5B50;&#x5173;&#x7CFB;&#x7684;&#x591A;&#x4E0A;&#x4E0B;&#x6587;&#xFF09;&#xFF0C;&#x6216;&#x8005;&#x504F;&#x5411;&#x4F7F;&#x7528; <strong>fluent</strong>&#xFF08;&#x6D41;&#x5F0F;&#xFF09;&#x6784;&#x5EFA;&#x5668; API&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>SpringApplicationBuilder</code>&#x3002;</p>
<p><code>SpringApplicationBuilder</code> &#x5141;&#x8BB8;&#x60A8;&#x94FE;&#x5F0F;&#x8C03;&#x7528;&#x591A;&#x4E2A;&#x65B9;&#x6CD5;&#xFF0C;&#x5305;&#x62EC;&#x80FD;&#x521B;&#x5EFA;&#x51FA;&#x5177;&#x6709;&#x5C42;&#x6B21;&#x7ED3;&#x6784;&#x7684; <code>parent</code> &#x548C; <code>child</code> &#x65B9;&#x6CD5;&#x3002;</p>
<p>&#x4F8B;&#x5982;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">new</span> <span class="token class-name">SpringApplicationBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">sources</span><span class="token punctuation">(</span><span class="token class-name">Parent</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">child</span><span class="token punctuation">(</span><span class="token class-name">Application</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">bannerMode</span><span class="token punctuation">(</span><span class="token class-name">Banner</span><span class="token punctuation">.</span><span class="token class-name">Mode</span><span class="token punctuation">.</span>OFF<span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span>args<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x521B;&#x5EFA;&#x5C42;&#x7EA7;&#x7684; <code>ApplicationContext</code> &#x65F6;&#x6709;&#x90E8;&#x5206;&#x9650;&#x5236;&#xFF0C;&#x6BD4;&#x5982; Web &#x7EC4;&#x4EF6;<strong>&#x5FC5;&#x987B;</strong>&#x5305;&#x542B;&#x5728;&#x5B50;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#xFF0C;&#x5E76;&#x4E14;&#x76F8;&#x540C;&#x7684; <code>Environment</code> &#x5C06;&#x4F5C;&#x7528;&#x4E8E;&#x7236;&#x5B50;&#x4E0A;&#x4E0B;&#x6587;&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/api/org/springframework/boot/builder/SpringApplicationBuilder.html" target="_blank">SpringApplicationBuilder Javadoc</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-application-events-and-listeners"></a></p>
<h3 id="235&#x3001;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E8B;&#x4EF6;&#x4E0E;&#x76D1;&#x542C;&#x5668;">23.5&#x3001;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E8B;&#x4EF6;&#x4E0E;&#x76D1;&#x542C;&#x5668;</h3>
<p>&#x9664;&#x4E86;&#x5E38;&#x89C1;&#x7684; Spring Framework &#x4E8B;&#x4EF6;&#xFF0C;&#x6BD4;&#x5982; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/context/event/ContextRefreshedEvent.html" target="_blank"><code>ContextRefreshedEvent</code></a>&#xFF0C;<code>SpringApplication</code> &#x8FD8;&#x4F1A;&#x53D1;&#x9001;&#x5176;&#x4ED6;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E8B;&#x4EF6;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5728; <code>ApplicationContext</code> &#x521B;&#x5EFA;&#x4E4B;&#x524D;&#xFF0C;&#x5B9E;&#x9645;&#x4E0A;&#x89E6;&#x53D1;&#x4E86;&#x4E00;&#x4E9B;&#x4E8B;&#x4EF6;&#xFF0C;&#x56E0;&#x6B64;&#x60A8;&#x4E0D;&#x80FD;&#x50CF; <code>@Bean</code> &#x4E00;&#x6837;&#x6CE8;&#x518C;&#x76D1;&#x542C;&#x5668;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7; <code>SpringApplication.addListeners(&#x200B;...)</code> &#x6216;&#x8005; <code>SpringApplicationBuilder.listeners(...&#x200B;)</code> &#x65B9;&#x6CD5;&#x6CE8;&#x518C;&#x5B83;&#x4EEC;&#x3002;&#x5982;&#x679C;&#x60A8;&#x5E0C;&#x671B;&#x65E0;&#x8BBA;&#x5E94;&#x7528;&#x4F7F;&#x7528;&#x4F55;&#x79CD;&#x521B;&#x5EFA;&#x65B9;&#x5F0F;&#x90FD;&#x80FD;&#x81EA;&#x52A8;&#x6CE8;&#x518C;&#x8FD9;&#x4E9B;&#x76D1;&#x542C;&#x5668;&#xFF0C;&#x60A8;&#x90FD;&#x53EF;&#x4EE5;&#x5C06; <code>META-INF/spring.factories</code> &#x6587;&#x4EF6;&#x6DFB;&#x52A0;&#x5230;&#x9879;&#x76EE;&#x4E2D;&#xFF0C;&#x5E76;&#x4F7F;&#x7528; <code>org.springframework.context.ApplicationListener</code> &#x5C5E;&#x6027;&#x952E;&#x6307;&#x5411;&#x60A8;&#x7684;&#x76D1;&#x542C;&#x5668;&#x3002;&#x6BD4;&#x5982;&#xFF1A;<code>org.springframework.context.ApplicationListener=com.example.project.MyListener</code></p>
</blockquote>
<p>&#x5F53;&#x60A8;&#x8FD0;&#x884C;&#x5E94;&#x7528;&#x65F6;&#xFF0C;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E8B;&#x4EF6;&#x5C06;&#x6309;&#x7167;&#x4EE5;&#x4E0B;&#x987A;&#x5E8F;&#x53D1;&#x9001;&#xFF1A;</p>
<ol>
<li>&#x5728;&#x5F00;&#x59CB;&#x5E94;&#x7528;&#x5F00;&#x59CB;&#x8FD0;&#x884C;&#x4F46;&#x8FD8;&#x6CA1;&#x6709;&#x8FDB;&#x884C;&#x4EFB;&#x4F55;&#x5904;&#x7406;&#x65F6;&#xFF08;&#x9664;&#x4E86;&#x6CE8;&#x518C;&#x76D1;&#x542C;&#x5668;&#x548C;&#x521D;&#x59CB;&#x5316;&#x5668;[initializer]&#xFF09;&#xFF0C;&#x5C06;&#x53D1;&#x9001; <code>ApplicationStartingEvent</code>&#x3002;</li>
<li>&#x5F53; <code>Environment</code> &#x88AB;&#x4E0A;&#x4E0B;&#x6587;&#x4F7F;&#x7528;&#xFF0C;&#x4F46;&#x662F;&#x5728;&#x4E0A;&#x4E0B;&#x6587;&#x521B;&#x5EFA;&#x4E4B;&#x524D;&#xFF0C;&#x5C06;&#x53D1;&#x9001; <code>ApplicationEnvironmentPreparedEvent</code>&#x3002;</li>
<li>&#x5728;&#x5F00;&#x59CB;&#x5237;&#x65B0;&#x4E4B;&#x524D;&#xFF0C;bean &#x5B9A;&#x4E49;&#x88AB;&#x52A0;&#x8F7D;&#x4E4B;&#x540E;&#x53D1;&#x9001; <code>ApplicationPreparedEvent</code>&#x3002;</li>
<li>&#x5728;&#x4E0A;&#x4E0B;&#x6587;&#x5237;&#x65B0;&#x4E4B;&#x540E;&#x4E14;&#x6240;&#x6709;&#x7684;&#x5E94;&#x7528;&#x548C;&#x547D;&#x4EE4;&#x884C;&#x8FD0;&#x884C;&#x5668;&#xFF08;command-line runner&#xFF09;&#x88AB;&#x8C03;&#x7528;&#x4E4B;&#x524D;&#x53D1;&#x9001; <code>ApplicationStartedEvent</code>&#x3002;</li>
<li>&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x548C;&#x547D;&#x4EE4;&#x884C;&#x8FD0;&#x884C;&#x5668;&#xFF08;command-line runner&#xFF09;&#x88AB;&#x8C03;&#x7528;&#x4E4B;&#x540E;&#xFF0C;&#x5C06;&#x53D1;&#x51FA; <code>ApplicationReadyEvent</code>&#xFF0C;&#x8BE5;&#x4E8B;&#x4EF6;&#x7528;&#x4E8E;&#x901A;&#x77E5;&#x5E94;&#x7528;&#x5DF2;&#x7ECF;&#x51C6;&#x5907;&#x5904;&#x7406;&#x8BF7;&#x6C42;&#x3002;</li>
<li>&#x5982;&#x679C;&#x542F;&#x52A8;&#x65F6;&#x53D1;&#x751F;&#x5F02;&#x5E38;&#xFF0C;&#x5C06;&#x53D1;&#x9001; <code>ApplicationFailedEvent</code>&#x3002;</li>
</ol>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x60A8;&#x53EF;&#x80FD;&#x4E0D;&#x4F1A;&#x7ECF;&#x5E38;&#x4F7F;&#x7528;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E8B;&#x4EF6;&#xFF0C;&#x4F46;&#x4E86;&#x89E3;&#x4ED6;&#x4EEC;&#x7684;&#x5B58;&#x5728;&#x8FD8;&#x662F;&#x5F88;&#x6709;&#x5FC5;&#x8981;&#x7684;&#x3002;&#x5728;&#x6846;&#x67B6;&#x5185;&#x90E8;&#xFF0C;Spring Boot &#x4F7F;&#x7528;&#x8FD9;&#x4E9B;&#x4E8B;&#x4EF6;&#x6765;&#x5904;&#x7406;&#x5404;&#x79CD;&#x4EFB;&#x52A1;&#x3002;</p>
</blockquote>
<p>&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E8B;&#x4EF6;&#x53D1;&#x9001;&#x4F7F;&#x7528;&#x4E86; Spring Framework &#x7684;&#x4E8B;&#x4EF6;&#x53D1;&#x5E03;&#x673A;&#x5236;&#x3002;&#x8BE5;&#x90E8;&#x5206;&#x673A;&#x5236;&#x786E;&#x4FDD;&#x5728;&#x5B50;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x53D1;&#x5E03;&#x7ED9;&#x76D1;&#x542C;&#x5668;&#x7684;&#x4E8B;&#x4EF6;&#x4E5F;&#x4F1A;&#x53D1;&#x5E03;&#x7ED9;&#x6240;&#x6709;&#x7956;&#x5148;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x7684;&#x76D1;&#x542C;&#x5668;&#x3002;&#x56E0;&#x6B64;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4F7F;&#x7528;&#x6709;&#x5C42;&#x7EA7;&#x7ED3;&#x6784;&#x7684; SpringApplication &#x5B9E;&#x4F8B;&#xFF0C;&#x5219;&#x76D1;&#x542C;&#x5668;&#x53EF;&#x80FD;&#x4F1A;&#x6536;&#x5230;&#x540C;&#x79CD;&#x7C7B;&#x578B;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E8B;&#x4EF6;&#x7684;&#x591A;&#x4E2A;&#x5B9E;&#x4F8B;&#x3002;</p>
<p>&#x4E3A;&#x4E86;&#x8BA9;&#x76D1;&#x542C;&#x5668;&#x80FD;&#x591F;&#x533A;&#x5206;&#x5176;&#x4E0A;&#x4E0B;&#x6587;&#x4E8B;&#x4EF6;&#x548C;&#x540E;&#x4EE3;&#x4E0A;&#x4E0B;&#x6587;&#x4E8B;&#x4EF6;&#xFF0C;&#x60A8;&#x5E94;&#x8BE5;&#x6CE8;&#x5165;&#x5176;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E0A;&#x4E0B;&#x6587;&#xFF0C;&#x7136;&#x540E;&#x5C06;&#x6CE8;&#x5165;&#x7684;&#x4E0A;&#x4E0B;&#x6587;&#x4E0E;&#x4E8B;&#x4EF6;&#x7684;&#x4E0A;&#x4E0B;&#x6587;&#x8FDB;&#x884C;&#x6BD4;&#x8F83;&#x3002;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5B9E;&#x73B0; <code>ApplicationContextAware</code> &#x6765;&#x6CE8;&#x5165;&#x4E0A;&#x4E0B;&#x6587;&#xFF0C;&#x5982;&#x679C;&#x76D1;&#x542C;&#x5668;&#x662F; bean&#xFF0C;&#x5219;&#x4F7F;&#x7528; <code>@Autowired</code> &#x6CE8;&#x5165;&#x4E0A;&#x4E0B;&#x6587;&#x3002;</p>
<p><a id="boot-features-web-environment"></a></p>
<h3 id="236&#x3001;web-&#x73AF;&#x5883;">23.6&#x3001;Web &#x73AF;&#x5883;</h3>
<p><code>SpringApplication</code> &#x8BD5;&#x56FE;&#x4E3A;&#x60A8;&#x521B;&#x5EFA;&#x6B63;&#x786E;&#x7C7B;&#x578B;&#x7684; <code>ApplicationContext</code>&#x3002;&#x786E;&#x5B9A; <code>WebApplicationType</code> &#x7684;&#x7B97;&#x6CD5;&#x975E;&#x5E38;&#x7B80;&#x5355;&#xFF1A;</p>
<ul>
<li>&#x5982;&#x679C;&#x5B58;&#x5728; Spring MVC&#xFF0C;&#x5219;&#x4F7F;&#x7528; <code>AnnotationConfigServletWebServerApplicationContext</code></li>
<li>&#x5982;&#x679C; Spring MVC &#x4E0D;&#x5B58;&#x5728;&#x4E14;&#x5B58;&#x5728; Spring WebFlux&#xFF0C;&#x5219;&#x4F7F;&#x7528; <code>AnnotationConfigReactiveWebServerApplicationContext</code></li>
<li>&#x5426;&#x5219;&#xFF0C;&#x4F7F;&#x7528; <code>AnnotationConfigApplicationContext</code></li>
</ul>
<p>&#x8FD9;&#x610F;&#x5473;&#x7740;&#x5982;&#x679C;&#x60A8;&#x5728;&#x540C;&#x4E00;&#x4E2A;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x4F7F;&#x7528;&#x4E86; Spring MVC &#x548C; Spring WebFlux &#x4E2D;&#x7684;&#x65B0; <code>WebClient</code>&#xFF0C;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#x5C06;&#x4F7F;&#x7528; Spring MVC&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8C03;&#x7528; <code>setWebApplicationType(WebApplicationType)</code> &#x4FEE;&#x6539;&#x9ED8;&#x8BA4;&#x884C;&#x4E3A;&#x3002;</p>
<p>&#x4E5F;&#x53EF;&#x4EE5;&#x8C03;&#x7528; <code>setApplicationContextClass(...)</code> &#x6765;&#x5B8C;&#x5168;&#x63A7;&#x5236; <code>ApplicationContext</code> &#x7C7B;&#x578B;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5728; JUnit &#x6D4B;&#x8BD5;&#x4E2D;&#x4F7F;&#x7528; <code>SpringApplication</code> &#x65F6;&#xFF0C;&#x901A;&#x5E38;&#x9700;&#x8981;&#x8C03;&#x7528; <code>setWebApplicationType(WebApplicationType.NONE)</code>&#x3002;</p>
</blockquote>
<p><a id="boot-features-application-arguments"></a></p>
<h3 id="237&#x3001;&#x8BBF;&#x95EE;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x53C2;&#x6570;">23.7&#x3001;&#x8BBF;&#x95EE;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x53C2;&#x6570;</h3>
<p>&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x8BBF;&#x95EE;&#x4ECE; <code>SpringApplication.run(&#x200B;...)</code> &#x4F20;&#x5165;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x53C2;&#x6570;&#xFF0C;&#x53EF;&#x4EE5;&#x6CE8;&#x5165;&#x4E00;&#x4E2A; <code>org.springframework.boot.ApplicationArguments</code> bean&#x3002;<code>ApplicationArguments</code> &#x63A5;&#x53E3;&#x63D0;&#x4F9B;&#x4E86;&#x8BBF;&#x95EE;&#x539F;&#x59CB; <code>String[]</code> &#x53C2;&#x6570;&#x4EE5;&#x53CA;&#x89E3;&#x6790;&#x540E;&#x7684; <code>option</code> &#x548C; <code>non-option</code> &#x53C2;&#x6570;&#x7684;&#x65B9;&#x6CD5;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">ApplicationArguments</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">boolean</span> debug <span class="token operator">=</span> args<span class="token punctuation">.</span><span class="token function">containsOption</span><span class="token punctuation">(</span><span class="token string">&quot;debug&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> files <span class="token operator">=</span> args<span class="token punctuation">.</span><span class="token function">getNonOptionArgs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// if run with &quot;--debug logfile.txt&quot; debug=true, files=[&quot;logfile.txt&quot;]</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>Spring Boot &#x8FD8;&#x5411; Spring <code>Environment</code> &#x6CE8;&#x518C;&#x4E86;&#x4E00;&#x4E2A; <code>CommandLinePropertySource</code>&#x3002;&#x8FD9;&#x5141;&#x8BB8;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@Value</code> &#x6CE8;&#x89E3;&#x6CE8;&#x5165;&#x5355;&#x4E2A;&#x5E94;&#x7528;&#x53C2;&#x6570;&#x3002;</p>
</blockquote>
<p><a id="boot-features-command-line-runner"></a></p>
<h3 id="238&#x3001;&#x4F7F;&#x7528;-applicationrunner-&#x6216;-commandlinerunner">23.8&#x3001;&#x4F7F;&#x7528; ApplicationRunner &#x6216; CommandLineRunner</h3>
<p>&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x5728; SpringApplication &#x542F;&#x52A8;&#x65F6;&#x8FD0;&#x884C;&#x4E00;&#x4E9B;&#x4EE3;&#x7801;&#xFF0C;&#x53EF;&#x4EE5;&#x5B9E;&#x73B0; <code>ApplicationRunner</code> &#x6216;&#x8005; <code>CommandLineRunner</code> &#x63A5;&#x53E3;&#x3002;&#x8FD9;&#x4E24;&#x4E2A;&#x63A5;&#x53E3;&#x7684;&#x5DE5;&#x4F5C;&#x65B9;&#x5F0F;&#x662F;&#x4E00;&#x6837;&#x7684;&#xFF0C;&#x90FD;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x5355;&#x72EC;&#x7684; <code>run</code> &#x65B9;&#x6CD5;&#xFF0C;&#x5B83;&#x5C06;&#x5728; <code>SpringApplication.run(&#x200B;...)</code> &#x5B8C;&#x6210;&#x4E4B;&#x524D;&#x8C03;&#x7528;&#x3002;</p>
<p><code>CommandLineRunner</code> &#x63A5;&#x53E3;&#x63D0;&#x4F9B;&#x4E86;&#x8BBF;&#x95EE;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5B57;&#x7B26;&#x4E32;&#x6570;&#x7EC4;&#x5F62;&#x5F0F;&#x53C2;&#x6570;&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x800C; <code>ApplicationRunner</code> &#x5219;&#x4F7F;&#x7528;&#x4E86;&#x4E0A;&#x8FF0;&#x7684; <code>ApplicationArguments</code> &#x63A5;&#x53E3;&#x3002;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A; <code>CommandLineRunner</code> &#x548C; <code>run</code> &#x65B9;&#x6CD5;&#x7684;&#x4F7F;&#x7528;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token keyword">implements</span> <span class="token class-name">CommandLineRunner</span> <span class="token punctuation">{</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// Do something...</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x5982;&#x679C;&#x60A8;&#x5B9A;&#x4E49;&#x4E86;&#x591A;&#x4E2A; <code>CommandLineRunner</code> &#x6216;&#x8005; <code>ApplicationRunner</code> bean&#xFF0C;&#x5219;&#x5FC5;&#x987B;&#x6307;&#x5B9A;&#x8C03;&#x7528;&#x987A;&#x5E8F;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5B9E;&#x73B0; <code>org.springframework.core.Ordered</code> &#x63A5;&#x53E3;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>org.springframework.core.annotation.Order</code> &#x6CE8;&#x89E3;&#x89E3;&#x51B3;&#x987A;&#x5E8F;&#x95EE;&#x9898;&#x3002;</p>
<p><a id="boot-features-application-exit"></a></p>
<h3 id="239&#x3001;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x9000;&#x51FA;">23.9&#x3001;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x9000;&#x51FA;</h3>
<p>&#x6BCF;&#x4E2A; <code>SpringApplication</code> &#x6CE8;&#x518C;&#x4E86;&#x4E00;&#x4E2A; JVM &#x5173;&#x95ED;&#x94A9;&#x5B50;&#xFF0C;&#x4EE5;&#x786E;&#x4FDD; <code>ApplicationContext</code> &#x5728;&#x9000;&#x51FA;&#x65F6;&#x53EF;&#x4EE5;&#x4F18;&#x96C5;&#x5173;&#x95ED;&#x3002;&#x6240;&#x6709;&#x6807;&#x51C6;&#x7684; Spring &#x751F;&#x547D;&#x5468;&#x671F;&#x56DE;&#x8C03;&#xFF08;&#x6BD4;&#x5982; <code>DisposableBean</code> &#x63A5;&#x53E3;&#xFF0C;&#x6216;&#x8005; <code>@PreDestroy</code> &#x6CE8;&#x89E3;&#xFF09;&#x90FD;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x3002;</p>
<p>&#x6B64;&#x5916;&#xFF0C;&#x5982;&#x679C;&#x5E0C;&#x671B;&#x5728;&#x8C03;&#x7528; <code>SpringApplication.exit()</code> &#x65F6;&#x8FD4;&#x56DE;&#x7279;&#x5B9A;&#x7684;&#x9000;&#x51FA;&#x7801;&#xFF0C;&#x5219; bean &#x53EF;&#x4EE5;&#x5B9E;&#x73B0; <code>org.springframework.boot.ExitCodeGenerator</code> &#x63A5;&#x53E3;&#x3002;&#x4E4B;&#x540E;&#x9000;&#x51FA;&#x7801;&#x5C06;&#x4F20;&#x9012;&#x7ED9; <code>System.exit()</code> &#x4EE5;&#x5C06;&#x5176;&#x4F5C;&#x4E3A;&#x72B6;&#x6001;&#x7801;&#x8FD4;&#x56DE;&#xFF0C;&#x5982;&#x793A;&#x4F8B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@SpringBootApplication</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ExitCodeApplication</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">ExitCodeGenerator</span> <span class="token function">exitCodeGenerator</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-&gt;</span> <span class="token number">42</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">System</span><span class="token punctuation">.</span><span class="token function">exit</span><span class="token punctuation">(</span><span class="token class-name">SpringApplication</span>
                <span class="token punctuation">.</span><span class="token function">exit</span><span class="token punctuation">(</span><span class="token class-name">SpringApplication</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token class-name">ExitCodeApplication</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> args<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x6B64;&#x5916;&#xFF0C;<code>ExitCodeGenerator</code> &#x63A5;&#x53E3;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5F02;&#x5E38;&#x5B9E;&#x73B0;&#x3002;&#x9047;&#x5230;&#x8FD9;&#x7C7B;&#x5F02;&#x5E38;&#x65F6;&#xFF0C;Spring Boot &#x5C06;&#x8FD4;&#x56DE;&#x5B9E;&#x73B0;&#x7684; <code>getExitCode()</code> &#x65B9;&#x6CD5;&#x63D0;&#x4F9B;&#x7684;&#x9000;&#x51FA;&#x7801;&#x3002;</p>
<p><a id="boot-features-application-admin"></a></p>
<h3 id="2310&#x3001;&#x7BA1;&#x7406;&#x529F;&#x80FD;">23.10&#x3001;&#x7BA1;&#x7406;&#x529F;&#x80FD;</h3>
<p>&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6307;&#x5B9A; <code>spring.application.admin.enabled</code> &#x5C5E;&#x6027;&#x6765;&#x4E3A;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x542F;&#x7528;&#x7BA1;&#x7406;&#x76F8;&#x5173;&#x7684;&#x529F;&#x80FD;&#x3002;&#x5176;&#x5C06;&#x5728; <code>MBeanServer</code> &#x5E73;&#x53F0;&#x4E0A;&#x66B4;&#x9732; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/admin/SpringApplicationAdminMXBean.java" target="_blank"><code>SpringApplicationAdminMXBean</code></a>&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x6B64;&#x529F;&#x80FD;&#x6765;&#x8FDC;&#x7A0B;&#x7BA1;&#x7406; Spring Boot &#x5E94;&#x7528;&#x3002;&#x8BE5;&#x529F;&#x80FD;&#x5BF9;&#x670D;&#x52A1;&#x5305;&#x88C5;&#x5668;&#x7684;&#x5B9E;&#x73B0;&#x4E5F;&#x662F;&#x975E;&#x5E38;&#x6709;&#x7528;&#x7684;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x60F3;&#x77E5;&#x9053;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5728;&#x54EA;&#x4E00;&#x4E2A; HTTP &#x7AEF;&#x53E3;&#x4E0A;&#x8FD0;&#x884C;&#xFF0C;&#x8BF7;&#x4F7F;&#x7528; <code>local.server.port</code> &#x952E;&#x83B7;&#x53D6;&#x8BE5;&#x5C5E;&#x6027;&#x3002;</p>
</blockquote>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x542F;&#x7528;&#x6B64;&#x529F;&#x80FD;&#x65F6;&#x8BF7;&#x5C0F;&#x5FC3;&#xFF0C;&#x56E0;&#x4E3A; MBean &#x66B4;&#x9732;&#x4E86;&#x5173;&#x95ED;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x65B9;&#x6CD5;&#x3002;</p>
</blockquote>
<p><a id="boot-features-external-config"></a></p>
<h2 id="24&#x3001;&#x5916;&#x90E8;&#x5316;&#x914D;&#x7F6E;">24&#x3001;&#x5916;&#x90E8;&#x5316;&#x914D;&#x7F6E;</h2>
<p>Spring Boot &#x53EF;&#x4EE5;&#x8BA9;&#x60A8;&#x7684;&#x914D;&#x7F6E;&#x5916;&#x90E8;&#x5316;&#xFF0C;&#x4EE5;&#x4FBF;&#x53EF;&#x4EE5;&#x5728;&#x4E0D;&#x540C;&#x73AF;&#x5883;&#x4E2D;&#x4F7F;&#x7528;&#x76F8;&#x540C;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4EE3;&#x7801;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; properties &#x6587;&#x4EF6;&#x3001;YAML &#x6587;&#x4EF6;&#x3001;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#x6216;&#x8005;&#x547D;&#x4EE4;&#x884C;&#x53C2;&#x6570;&#x6765;&#x5916;&#x90E8;&#x5316;&#x914D;&#x7F6E;&#x3002;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@Value</code> &#x6CE8;&#x89E3;&#x5C06;&#x5C5E;&#x6027;&#x503C;&#x76F4;&#x63A5;&#x6CE8;&#x5165;&#x5230; bean &#x4E2D;&#xFF0C;&#x53EF;&#x901A;&#x8FC7; Spring &#x7684; <code>Environment</code> &#x8BBF;&#x95EE;&#xFF0C;&#x6216;&#x8005;&#x901A;&#x8FC7; <code>@ConfigurationProperties</code> &#x7ED1;&#x5B9A;&#x5230;<a href="#boot-features-external-config-typesafe-configuration-properties">&#x7ED3;&#x6784;&#x5316;&#x5BF9;&#x8C61;</a>&#x3002;</p>
<p>Spring Boot &#x4F7F;&#x7528;&#x4E86;&#x4E00;&#x4E2A;&#x975E;&#x5E38;&#x7279;&#x522B;&#x7684; <code>PropertySource</code> &#x6307;&#x4EE4;&#xFF0C;&#x7528;&#x4E8E;&#x667A;&#x80FD;&#x8986;&#x76D6;&#x9ED8;&#x8BA4;&#x503C;&#x3002;&#x5C5E;&#x6027;&#x5C06;&#x6309;&#x7167;&#x4EE5;&#x4E0B;&#x987A;&#x5E8F;&#x5904;&#x7406;&#xFF1A;</p>
<ol>
<li>&#x5728;&#x60A8;&#x7684;&#x4E3B;&#x76EE;&#x5F55;&#xFF08;&#x5F53; devtools &#x88AB;&#x6FC0;&#x6D3B;&#xFF0C;&#x5219;&#x4E3A; <code>~/.spring-boot-devtools.properties</code> &#xFF09;&#x4E2D;&#x7684; <a href="#using-boot-devtools-globalsettings">Devtools &#x5168;&#x5C40;&#x8BBE;&#x7F6E;&#x5C5E;&#x6027;</a>&#x3002;</li>
<li>&#x5728;&#x6D4B;&#x8BD5;&#x4E2D;&#x4F7F;&#x7528;&#x5230;&#x7684; <code>@TestPropertySource</code> &#x6CE8;&#x89E3;&#x3002;</li>
<li>&#x5728;&#x6D4B;&#x8BD5;&#x4E2D;&#x4F7F;&#x7528;&#x5230;&#x7684; <code>properties</code> &#x5C5E;&#x6027;&#xFF0C;&#x53EF;&#x4EE5;&#x662F; <a href="https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/api/org/springframework/boot/test/context/SpringBootTest.html" target="_blank"><code>@SpringBootTest</code></a> &#x548C;<a href="#boot-features-testing-spring-boot-applications-testing-autoconfigured-tests">&#x7528;&#x4E8E;&#x6D4B;&#x8BD5;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x67D0;&#x90E8;&#x5206;&#x7684;&#x6D4B;&#x8BD5;&#x6CE8;&#x89E3;</a>&#x3002;</li>
<li>&#x547D;&#x4EE4;&#x884C;&#x53C2;&#x6570;&#x3002;</li>
<li>&#x6765;&#x81EA; <code>SPRING_APPLICATION_JSON</code> &#x7684;&#x5C5E;&#x6027;&#xFF08;&#x5D4C;&#x5165;&#x5728;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#x6216;&#x8005;&#x7CFB;&#x7EDF;&#x5C5E;&#x6027;&#x3010;system propert&#x3011;&#x4E2D;&#x7684;&#x5185;&#x8054; JSON&#xFF09;&#x3002;</li>
<li><code>ServletConfig</code> &#x521D;&#x59CB;&#x5316;&#x53C2;&#x6570;&#x3002;</li>
<li><code>ServletContext</code> &#x521D;&#x59CB;&#x5316;&#x53C2;&#x6570;&#x3002;</li>
<li>&#x6765;&#x81EA; <code>java:comp/env</code> &#x7684; JNDI &#x5C5E;&#x6027;&#x3002;</li>
<li>Java &#x7CFB;&#x7EDF;&#x5C5E;&#x6027;&#xFF08;<code>System.getProperties()</code>&#xFF09;&#x3002;</li>
<li>&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#x3002;</li>
<li>&#x53EA;&#x6709; <code>random.*</code> &#x5C5E;&#x6027;&#x7684; <code>RandomValuePropertySource</code>&#x3002;</li>
<li>&#x5728;&#x5DF2;&#x6253;&#x5305;&#x7684; jar &#x5916;&#x90E8;&#x7684;<a href="#boot-features-external-config-profile-specific-properties">&#x6307;&#x5B9A; profile &#x7684;&#x5E94;&#x7528;&#x5C5E;&#x6027;&#x6587;&#x4EF6;</a>&#xFF08;<code>application-{profile}.properties</code> &#x548C; YAML &#x53D8;&#x91CF;&#xFF09;&#x3002;</li>
<li>&#x5728;&#x5DF2;&#x6253;&#x5305;&#x7684; jar &#x5185;&#x90E8;&#x7684;<a href="#boot-features-external-config-profile-specific-properties">&#x6307;&#x5B9A; profile &#x7684;&#x5E94;&#x7528;&#x5C5E;&#x6027;&#x6587;&#x4EF6;</a>&#xFF08;<code>application-{profile}.properties</code> &#x548C; YAML &#x53D8;&#x91CF;&#xFF09;&#x3002;</li>
<li>&#x5728;&#x5DF2;&#x6253;&#x5305;&#x7684; jar &#x5916;&#x90E8;&#x7684;&#x5E94;&#x7528;&#x5C5E;&#x6027;&#x6587;&#x4EF6;&#xFF08;<code>application.properties</code> &#x548C; YAML &#x53D8;&#x91CF;&#xFF09;&#x3002;</li>
<li>&#x5728;&#x5DF2;&#x6253;&#x5305;&#x7684; jar &#x5185;&#x90E8;&#x7684;&#x5E94;&#x7528;&#x5C5E;&#x6027;&#x6587;&#x4EF6;&#xFF08;<code>application.properties</code> &#x548C; YAML &#x53D8;&#x91CF;&#xFF09;&#x3002;</li>
<li>&#x5728; <code>@Configuration</code> &#x7C7B;&#x4E0A;&#x7684; <code>@PropertySource</code> &#x6CE8;&#x89E3;&#x3002;</li>
<li>&#x9ED8;&#x8BA4;&#x5C5E;&#x6027;&#xFF08;&#x4F7F;&#x7528; <code>SpringApplication.setDefaultProperties</code> &#x6307;&#x5B9A;&#xFF09;&#x3002;</li>
</ol>
<p>&#x4E3E;&#x4E2A;&#x4F8B;&#x5B50;&#xFF0C;&#x5047;&#x8BBE;&#x5F00;&#x53D1;&#x7684; <code>@Component</code> &#x4F7F;&#x7528;&#x4E86; <code>name</code> &#x5C5E;&#x6027;&#xFF0C;&#x53EF;&#x4EE5;&#x8FD9;&#x6837;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Value</span><span class="token punctuation">(</span><span class="token string">&quot;${name}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x5728;&#x60A8;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684; classpath &#x4E2D;&#xFF08;&#x6BD4;&#x5982;&#x5728; jar &#x4E2D;&#xFF09;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x6709;&#x4E00;&#x4E2A; <code>application.properties</code>&#xFF0C;&#x5B83;&#x4E3A; <code>name</code> &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x5408;&#x9002;&#x7684;&#x9ED8;&#x8BA4;&#x5C5E;&#x6027;&#x503C;&#x3002;&#x5F53;&#x5728;&#x65B0;&#x73AF;&#x5883;&#x4E2D;&#x8FD0;&#x884C;&#x65F6;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728; jar &#x5916;&#x9762;&#x63D0;&#x4F9B;&#x4E00;&#x4E2A; <code>application.properties</code> &#x6765;&#x8986;&#x76D6; <code>name</code>&#x3002;&#x5BF9;&#x4E8E;&#x4E00;&#x6B21;&#x6027;&#x6D4B;&#x8BD5;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x547D;&#x4EE4;&#x884C;&#x6307;&#x5B9A;&#x5F62;&#x5F0F;&#x542F;&#x52A8;&#xFF08;&#x6BD4;&#x5982; <code>java -jar app.jar --name=&quot;Spring&quot;</code>&#xFF09;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>

`SPRING_APPLICATION_JSON` &#x5C5E;&#x6027;&#x53EF;&#x4EE5;&#x5728;&#x547D;&#x4EE4;&#x884C;&#x4E2D;&#x63D0;&#x4F9B;&#x4E00;&#x4E2A;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#x3002;&#x6BD4;&#x5982;&#x5728; UN*X shell &#x4E2D;&#xFF1A;

```
$ SPRING_APPLICATION_JSON=&apos;{&quot;acme&quot;:{&quot;name&quot;:&quot;test&quot;}}&apos; java -jar myapp.jar
```

&#x5728;&#x6B64;&#x793A;&#x4F8B;&#x4E2D;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728; Spring `Environment` &#x4E2D;&#x4F7F;&#x7528; `acme.name=test`&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x5728;&#x7CFB;&#x7EDF;&#x5C5E;&#x6027;&#xFF08;System property&#xFF09;&#x4E2D;&#x5C06; JSON &#x4F5C;&#x4E3A; `spring.application.json` &#x5C5E;&#x6027;&#x63D0;&#x4F9B;&#xFF1A;

```
$ java -Dspring.application.json=&apos;{&quot;name&quot;:&quot;test&quot;}&apos; -jar myapp.jar
```

&#x6216;&#x8005;&#x4EE5;&#x547D;&#x4EE4;&#x884C;&#x53C2;&#x6570;&#x5F62;&#x5F0F;&#xFF1A;

```
$ java -jar myapp.jar --spring.application.json=&apos;{&quot;name&quot;:&quot;test&quot;}&apos;
```

&#x6216;&#x8005;&#x5C06; JSON &#x4F5C;&#x4E3A;&#x4E00;&#x4E2A; JNDI &#x53D8;&#x91CF;&#xFF1A;`java:comp/env/spring.application.json`&#x3002;

</blockquote>

<p><a id="boot-features-external-config-random-values"></a></p>
<h3 id="241&#x3001;&#x914D;&#x7F6E;&#x968F;&#x673A;&#x503C;">24.1&#x3001;&#x914D;&#x7F6E;&#x968F;&#x673A;&#x503C;</h3>
<p><code>RandomValuePropertySource</code> &#x5BF9;&#x4E8E;&#x968F;&#x673A;&#x503C;&#x6CE8;&#x5165;&#x975E;&#x5E38;&#x6709;&#x7528;&#xFF08;&#x6BD4;&#x5982;&#x5728;&#x4FDD;&#x5BC6;&#x573A;&#x666F;&#x6216;&#x8005;&#x6D4B;&#x8BD5;&#x7528;&#x4F8B;&#x4E2D;)&#x3002;&#x5B83;&#x53EF;&#x4EE5;&#x4EA7;&#x751F; integer&#x3001;long&#x3001;uuid &#x548C; string&#x3002;&#x5982;&#x4E0B;&#x793A;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">my.secret</span><span class="token attr-value"><span class="token punctuation">=</span>${random.value}</span>
<span class="token constant">my.number</span><span class="token attr-value"><span class="token punctuation">=</span>${random.int}</span>
<span class="token constant">my.bignumber</span><span class="token attr-value"><span class="token punctuation">=</span>${random.long}</span>
<span class="token constant">my.uuid</span><span class="token attr-value"><span class="token punctuation">=</span>${random.uuid}</span>
<span class="token constant">my.number.less.than.ten</span><span class="token attr-value"><span class="token punctuation">=</span>${random.int(10)}</span>
<span class="token constant">my.number.in.range</span><span class="token attr-value"><span class="token punctuation">=</span>${random.int[1024,65536]}</span>
</code></pre>
<p><code>random.int*</code> &#x8BED;&#x6CD5;&#x4E3A; <code>OPEN value (,max) CLOSE</code>&#xFF0C;<code>OPEN,CLOSE</code> &#x53EF;&#x4E3A;&#x4EFB;&#x610F;&#x5B57;&#x7B26;&#xFF0C;<code>value,max</code> &#x4E3A;&#x6574;&#x6570;&#x3002;&#x5982;&#x679C;&#x4F7F;&#x7528;&#x4E86; <code>max</code>&#xFF0C;<code>value</code> &#x5219;&#x4E3A;&#x6700;&#x5C0F;&#x503C;&#xFF0C;<code>max</code> &#x4E3A;&#x6700;&#x5927;&#x503C;&#x3002;</p>
<p><a id="boot-features-external-config-command-line-args"></a></p>
<h3 id="242&#x3001;&#x8BBF;&#x95EE;&#x547D;&#x4EE4;&#x884C;&#x5C5E;&#x6027;">24.2&#x3001;&#x8BBF;&#x95EE;&#x547D;&#x4EE4;&#x884C;&#x5C5E;&#x6027;</h3>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;<code>SpringApplication</code> &#x5C06;&#x6240;&#x6709;&#x547D;&#x4EE4;&#x884C;&#x9009;&#x9879;&#x53C2;&#x6570;&#xFF08;&#x5373;&#x4EE5; <code>--</code> &#x5F00;&#x5934;&#x7684;&#x53C2;&#x6570;&#xFF0C;&#x6BD4;&#x5982; <code>--server.port=9000</code>&#xFF09;&#x8F6C;&#x6362;&#x4E3A;&#x5C5E;&#x6027;&#xFF0C;&#x5E76;&#x5C06;&#x5B83;&#x4EEC;&#x6DFB;&#x52A0;&#x5230; Spring <code>Environment</code> &#x4E2D;&#x3002;&#x5982;&#x4E4B;&#x524D;&#x6240;&#x8FF0;&#xFF0C;&#x547D;&#x4EE4;&#x884C;&#x5C5E;&#x6027;&#x59CB;&#x7EC8;&#x4F18;&#x5148;&#x4E8E;&#x5176;&#x4ED6;&#x5C5E;&#x6027;&#x6E90;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x4E0D;&#x5E0C;&#x671B;&#x5C06;&#x547D;&#x4EE4;&#x884C;&#x5C5E;&#x6027;&#x6DFB;&#x52A0;&#x5230; <code>Environment</code>&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>SpringApplication.setAddCommandLineProperties(false)</code> &#x6765;&#x7981;&#x7528;&#x5B83;&#x4EEC;&#x3002;</p>
<p><a id="boot-features-external-config-application-property-files"></a></p>
<h3 id="243&#x3001;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5C5E;&#x6027;&#x6587;&#x4EF6;">24.3&#x3001;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5C5E;&#x6027;&#x6587;&#x4EF6;</h3>
<p><code>SpringApplication</code> &#x4ECE;&#x4EE5;&#x4E0B;&#x4F4D;&#x7F6E;&#x7684; <code>application.properties</code> &#x6587;&#x4EF6;&#x4E2D;&#x52A0;&#x8F7D;&#x5C5E;&#x6027;&#xFF08;properties&#xFF09;&#xFF0C;&#x5E76;&#x5C06;&#x5B83;&#x4EEC;&#x6DFB;&#x52A0;&#x5230; Spring <code>Environment</code> &#x4E2D;&#xFF1A;</p>
<ol>
<li>&#x5F53;&#x524D;&#x76EE;&#x5F55;&#x7684; <code>/config</code> &#x5B50;&#x76EE;&#x5F55;</li>
<li>&#x5F53;&#x524D;&#x76EE;&#x5F55;</li>
<li>classpath &#x4E0A;&#x7684; <code>/config</code> &#x5305;</li>
<li>classpath &#x6839;&#x8DEF;&#x5F84;</li>
</ol>
<p>&#x5217;&#x8868;&#x6309;&#x5E8F;&#x53F7;&#x4F18;&#x5148;&#x7EA7;&#x6392;&#x5E8F;&#xFF0C;&#x5E8F;&#x53F7;&#x8D8A;&#x5C0F;&#xFF0C;&#x4F18;&#x5148;&#x7EA7;&#x8D8A;&#x9AD8;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <a href="#boot-features-external-config-yaml">YAML&#xFF08;.yml&#xFF09;</a>&#x6587;&#x4EF6;&#x6765;&#x66FF;&#x4EE3; <strong>.properties</strong>&#x3002;</p>
</blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x4E0D;&#x559C;&#x6B22; <code>application.properties</code> &#x4F5C;&#x4E3A;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x540D;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6307;&#x5B9A; <code>spring.config.name</code> &#x73AF;&#x5883;&#x5C5E;&#x6027;&#x6765;&#x5207;&#x6362;&#x5230;&#x53E6;&#x4E00;&#x4E2A;&#x6587;&#x4EF6;&#x540D;&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.config.location</code> &#x73AF;&#x5883;&#x5C5E;&#x6027;&#x6765;&#x5F15;&#x7528;&#x4E00;&#x4E2A;&#x663E;&#x5F0F;&#x4F4D;&#x7F6E;&#xFF08;&#x4EE5;&#x9017;&#x53F7;&#x5206;&#x9694;&#x7684;&#x76EE;&#x5F55;&#x4F4D;&#x7F6E;&#x6216;&#x6587;&#x4EF6;&#x8DEF;&#x5F84;&#x5217;&#x8868;&#xFF09;&#x3002;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x6307;&#x5B9A;&#x5176;&#x4ED6;&#x6587;&#x4EF6;&#x540D;&#xFF1A;</p>
<pre class="language-"><code>$ java -jar myproject.jar --spring.config.name=myproject
</code></pre><p>&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x6307;&#x5B9A;&#x4E24;&#x4E2A;&#x4F4D;&#x7F6E;&#xFF1A;</p>
<pre class="language-"><code>$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
</code></pre><p><strong>&#x8B66;&#x544A;</strong></p>
<blockquote>
<p><code>spring.config.name</code> &#x548C; <code>spring.config.location</code> &#x5728;&#x7A0B;&#x5E8F;&#x542F;&#x52A8;&#x65E9;&#x671F;&#x5C31;&#x7528;&#x6765;&#x786E;&#x5B9A;&#x54EA;&#x4E9B;&#x6587;&#x4EF6;&#x5FC5;&#x987B;&#x52A0;&#x8F7D;&#xFF0C;&#x56E0;&#x6B64;&#x5FC5;&#x987B;&#x5C06;&#x5B83;&#x4EEC;&#x5B9A;&#x4E49;&#x4E3A;&#x73AF;&#x5883;&#x5C5E;&#x6027;&#xFF08;&#x901A;&#x5E38;&#x662F; OS &#x73AF;&#x5883;&#x53D8;&#x91CF;&#x3001;&#x7CFB;&#x7EDF;&#x5C5E;&#x6027;&#x6216;&#x547D;&#x4EE4;&#x884C;&#x53C2;&#x6570;&#xFF09;&#x3002;</p>
</blockquote>
<p>&#x5982;&#x679C; <code>spring.config.location</code> &#x5305;&#x542B;&#x76EE;&#x5F55;&#xFF08;&#x800C;&#x4E0D;&#x662F;&#x6587;&#x4EF6;&#xFF09;&#xFF0C;&#x5219;&#x5B83;&#x4EEC;&#x5E94;&#x8BE5;&#x4EE5; <code>/</code> &#x7ED3;&#x5C3E;&#xFF08;&#x5E76;&#x4E14;&#x5728;&#x8FD0;&#x884C;&#x671F;&#x95F4;&#xFF0C;&#x5728;&#x52A0;&#x8F7D;&#x4E4B;&#x524D;&#x8FFD;&#x52A0;&#x4ECE; <code>spring.config.name</code> &#x751F;&#x6210;&#x7684;&#x540D;&#x79F0;&#xFF0C;&#x5305;&#x62EC;&#x6307;&#x5B9A; profile &#x7684;&#x6587;&#x4EF6;&#x540D;&#xFF09;&#x3002; <code>spring.config.location</code> &#x4E2D;&#x6307;&#x5B9A;&#x7684;&#x6587;&#x4EF6;&#x6309;&#x539F;&#x6837;&#x4F7F;&#x7528;&#xFF0C;&#x4E0D;&#x652F;&#x6301;&#x6307;&#x5B9A; profile &#x5F62;&#x5F0F;&#xFF0C;&#x5E76;&#x4E14;&#x53EF;&#x88AB;&#x4EFB;&#x4F55;&#x6307;&#x5B9A; profile &#x7684;&#x6587;&#x4EF6;&#x7684;&#x5C5E;&#x6027;&#x6240;&#x8986;&#x76D6;&#x3002;</p>
<p>&#x914D;&#x7F6E;&#x4F4D;&#x7F6E;&#x4EE5;&#x76F8;&#x53CD;&#x7684;&#x987A;&#x5E8F;&#x641C;&#x7D22;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x914D;&#x7F6E;&#x7684;&#x4F4D;&#x7F6E;&#x4E3A; <code>classpath:/,classpath:/config/,file:./,file:./config/</code>&#x3002;&#x751F;&#x6210;&#x7684;&#x641C;&#x7D22;&#x987A;&#x5E8F;&#x5982;&#x4E0B;&#xFF1A;</p>
<ol>
<li><code>file:./config/</code></li>
<li><code>file:./</code></li>
<li><code>classpath:/config/</code></li>
<li><code>classpath:/</code></li>
</ol>
<p>&#x4F7F;&#x7528;&#x4E86; <code>spring.config.location</code> &#x914D;&#x7F6E;&#x81EA;&#x5B9A;&#x4E49;&#x914D;&#x7F6E;&#x4F4D;&#x7F6E;&#x65F6;&#xFF0C;&#x9ED8;&#x8BA4;&#x4F4D;&#x7F6E;&#x914D;&#x7F6E;&#x5C06;&#x88AB;&#x66FF;&#x4EE3;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5982;&#x679C; <code>spring.config.location</code> &#x914D;&#x7F6E;&#x4E3A; <code>classpath:/custom-config/,file:./custom-config/</code>&#xFF0C;&#x641C;&#x7D22;&#x987A;&#x5E8F;&#x5C06;&#x53D8;&#x4E3A;&#x4EE5;&#x4E0B;&#xFF1A;</p>
<ol>
<li><code>file:./custom-config/</code></li>
<li><code>classpath:custom-config/</code></li>
</ol>
<p>&#x6216;&#x8005;&#xFF0C;&#x5F53;&#x4F7F;&#x7528; <code>spring.config.additional-location</code> &#x914D;&#x7F6E;&#x81EA;&#x5B9A;&#x4E49;&#x914D;&#x7F6E;&#x4F4D;&#x7F6E;&#x65F6;&#xFF0C;&#x9664;&#x4E86;&#x4F7F;&#x7528;&#x9ED8;&#x8BA4;&#x4F4D;&#x7F6E;&#x5916;&#xFF0C;&#x8FD8;&#x4F1A;&#x4F7F;&#x7528;&#x5B83;&#x4EEC;&#x3002;&#x8FD9;&#x4E9B;&#x5176;&#x4ED6;&#xFF08;additional&#xFF09;&#x4F4D;&#x7F6E;&#x5C06;&#x5728;&#x9ED8;&#x8BA4;&#x4F4D;&#x7F6E;&#x4E4B;&#x524D;&#x641C;&#x7D22;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5982;&#x679C;&#x5C06;&#x5176;&#x4ED6;&#x4F4D;&#x7F6E;&#x914D;&#x7F6E;&#x4E3A; <code>classpath:/custom-config/,file:./custom-config/</code>&#xFF0C;&#x5219;&#x641C;&#x7D22;&#x987A;&#x5E8F;&#x5C06;&#x53D8;&#x4E3A;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;&#xFF1A;</p>
<ol>
<li><code>file:./custom-config/</code></li>
<li><code>classpath:custom-config/</code></li>
<li><code>file:./config/</code></li>
<li><code>file:./</code></li>
<li><code>classpath:/config/</code></li>
<li><code>classpath:/</code></li>
</ol>
<p>&#x8BE5;&#x641C;&#x7D22;&#x987A;&#x5E8F;&#x5141;&#x8BB8;&#x60A8;&#x5728;&#x4E00;&#x4E2A;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4E2D;&#x6307;&#x5B9A;&#x9ED8;&#x8BA4;&#x503C;&#xFF0C;&#x7136;&#x540E;&#x6709;&#x9009;&#x62E9;&#x5730;&#x8986;&#x76D6;&#x53E6;&#x4E00;&#x4E2A;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4E2D;&#x7684;&#x503C;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>application.properties</code>&#xFF08;&#x6216;&#x60A8;&#x4F7F;&#x7528; <code>spring.config.name</code> &#x6307;&#x5B9A;&#x7684;&#x5176;&#x4ED6;&#x6587;&#x4EF6;&#xFF09;&#x4E2D;&#x7684;&#x67D0;&#x4E2A;&#x9ED8;&#x8BA4;&#x4F4D;&#x7F6E;&#x4E3A;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x63D0;&#x4F9B;&#x9ED8;&#x8BA4;&#x503C;&#x3002;&#x4E4B;&#x540E;&#xFF0C;&#x5728;&#x8FD0;&#x884C;&#x65F6;&#xFF0C;&#x8FD9;&#x4E9B;&#x9ED8;&#x8BA4;&#x503C;&#x5C06;&#x88AB;&#x81EA;&#x5B9A;&#x4E49;&#x4F4D;&#x7F6E;&#x4E2D;&#x7684;&#x67D0;&#x4E2A;&#x6587;&#x4EF6;&#x6240;&#x8986;&#x76D6;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528;&#x7684;&#x662F;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#x800C;&#x4E0D;&#x662F;&#x7CFB;&#x7EDF;&#x5C5E;&#x6027;&#xFF0C;&#x5927;&#x90E8;&#x5206;&#x64CD;&#x4F5C;&#x7CFB;&#x7EDF;&#x90FD;&#x4E0D;&#x5141;&#x8BB8;&#x4F7F;&#x7528; <code>.</code> &#x5206;&#x9694;&#x7684;&#x952E;&#x540D;&#xFF0C;&#x4F46;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4E0B;&#x5212;&#x7EBF;&#x6765;&#x4EE3;&#x66FF;&#xFF08;&#x4F8B;&#x5982;&#xFF0C;&#x4F7F;&#x7528; <code>SPRING_CONFIG_NAME</code> &#x800C;&#x4E0D;&#x662F; <code>spring.config.name</code>&#xFF09;&#x3002;</p>
</blockquote>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5728;&#x5BB9;&#x5668;&#x4E2D;&#x8FD0;&#x884C;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; JNDI &#x5C5E;&#x6027;&#xFF08;<code>java:comp/env</code>&#xFF09;&#x6216; servlet &#x4E0A;&#x4E0B;&#x6587;&#x521D;&#x59CB;&#x5316;&#x53C2;&#x6570;&#x6765;&#x4EE3;&#x66FF;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#x6216;&#x7CFB;&#x7EDF;&#x5C5E;&#x6027;&#x3002;</p>
</blockquote>
<p><a id="boot-features-external-config-profile-specific-properties"></a></p>
<h3 id="244&#x3001;&#x7279;&#x5B9A;-profile-&#x7684;&#x5C5E;&#x6027;&#x6587;&#x4EF6;">24.4&#x3001;&#x7279;&#x5B9A; Profile &#x7684;&#x5C5E;&#x6027;&#x6587;&#x4EF6;</h3>
<p>&#x9664; <code>application.properties</code> &#x6587;&#x4EF6;&#x5916;&#xFF0C;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4EE5;&#x4E0B;&#x547D;&#x540D;&#x7EA6;&#x5B9A;&#x5B9A;&#x4E49;&#x7279;&#x5B9A; profile &#x7684;&#x5C5E;&#x6027;&#x6587;&#x4EF6;&#xFF1A;<code>application-{profile}.properties</code>&#x3002;<code>Environment</code> &#x6709;&#x4E00;&#x7EC4;&#x9ED8;&#x8BA4;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#xFF08;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#x4E3A; <code>default</code>&#xFF09;&#xFF0C;&#x5982;&#x679C;&#x672A;&#x8BBE;&#x7F6E;&#x6FC0;&#x6D3B;&#x7684;&#xFF08;active&#xFF09;profile&#xFF0C;&#x5219;&#x4F7F;&#x7528;&#x8FD9;&#x4E9B;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x3002;&#x6362;&#x53E5;&#x8BDD;&#x8BF4;&#xFF0C;&#x5982;&#x679C;&#x6CA1;&#x6709;&#x663E;&#x5F0F;&#x6FC0;&#x6D3B; profile&#xFF0C;&#x5219;&#x4F1A;&#x52A0;&#x8F7D; <code>application-default.properties</code> &#x4E2D;&#x7684;&#x5C5E;&#x6027;&#x3002;</p>
<p>&#x7279;&#x5B9A; profile &#x7684;&#x5C5E;&#x6027;&#x6587;&#x4EF6;&#x4ECE;&#x4E0E;&#x6807;&#x51C6; <code>application.properties</code> &#x76F8;&#x540C;&#x7684;&#x4F4D;&#x7F6E;&#x52A0;&#x8F7D;&#xFF0C;&#x7279;&#x5B9A; profile &#x7684;&#x5C5E;&#x6027;&#x6587;&#x4EF6;&#x65E0;&#x8BBA;&#x662F;&#x5426;&#x5728;&#x6253;&#x5305;&#x7684; jar &#x5185;&#x90E8;&#xFF0C;&#x90FD;&#x59CB;&#x7EC8;&#x8986;&#x76D6;&#x975E;&#x7279;&#x5B9A;&#x6587;&#x4EF6;&#x3002;</p>
<p>&#x5982;&#x679C;&#x6307;&#x5B9A;&#x4E86;&#x591A;&#x4E2A;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#xFF0C;&#x5219;&#x5E94;&#x7528; last-wins &#x7B56;&#x7565;&#xFF08;&#x4F18;&#x5148;&#x91C7;&#x53D6;&#x6700;&#x540E;&#x4E00;&#x4E2A;&#xFF09;&#x3002;&#x4F8B;&#x5982;&#xFF0C;<code>spring.profiles.active</code> &#x5C5E;&#x6027;&#x6307;&#x5B9A;&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x662F;&#x5728;&#x4F7F;&#x7528; <code>SpringApplication</code> API &#x914D;&#x7F6E;&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4E4B;&#x540E;&#x6DFB;&#x52A0;&#x7684;&#xFF0C;&#x56E0;&#x6B64;&#x4F18;&#x5148;&#x5E94;&#x7528;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x5728; <code>spring.config.location</code> &#x4E2D;&#x6307;&#x5B9A;&#x4E86;&#x6587;&#x4EF6;&#xFF0C;&#x5219;&#x4E0D;&#x8003;&#x8651;&#x8FD9;&#x4E9B;&#x6587;&#x4EF6;&#x7684;&#x7279;&#x5B9A; profile &#x5F62;&#x5F0F;&#x3002;&#x5982;&#x679C;&#x60A8;&#x8FD8;&#x60F3;&#x4F7F;&#x7528;&#x7279;&#x5B9A; profile &#x7684;&#x5C5E;&#x6027;&#x6587;&#x4EF6;&#xFF0C;&#x8BF7;&#x5728; <code>spring.config.location</code> &#x4E2D;&#x4F7F;&#x7528;&#x76EE;&#x5F55;&#x5F62;&#x5F0F;&#x3002;</p>
</blockquote>
<p><a id="boot-features-external-config-placeholders-in-properties"></a></p>
<h3 id="245&#x3001;&#x5C5E;&#x6027;&#x4E2D;&#x7684;&#x5360;&#x4F4D;&#x7B26;">24.5&#x3001;&#x5C5E;&#x6027;&#x4E2D;&#x7684;&#x5360;&#x4F4D;&#x7B26;</h3>
<p><code>application.properties</code> &#x4E2D;&#x7684;&#x503C;&#x5728;&#x4F7F;&#x7528;&#x65F6;&#x901A;&#x8FC7;&#x73B0;&#x6709;&#x7684; <code>Environment</code> &#x8FDB;&#x884C;&#x8FC7;&#x6EE4;&#xFF0C;&#x56E0;&#x6B64;&#x60A8;&#x53EF;&#x4EE5;&#x8FD4;&#x56DE;&#x4E4B;&#x524D;&#x5B9A;&#x4E49;&#x7684;&#x503C;&#xFF08;&#x4F8B;&#x5982;&#xFF0C;&#x4ECE;&#x7CFB;&#x7EDF;&#x5C5E;&#x6027;&#xFF09;&#x3002;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">app.name</span><span class="token attr-value"><span class="token punctuation">=</span>MyApp</span>
<span class="token constant">app.description</span><span class="token attr-value"><span class="token punctuation">=</span>${app.name} is a Spring Boot application</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x6B64;&#x6280;&#x672F;&#x521B;&#x5EFA;&#x73B0;&#x6709; Spring Boot &#x5C5E;&#x6027;&#x7684;<strong>&#x7B80;&#x77ED;</strong>&#x5F62;&#x5F0F;&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x89C1;<a href="hwo-to.md#howto-use-short-command-line-arguments">&#x7B2C; 77.4 &#x7AE0;&#x8282;&#xFF1A;&#x4F7F;&#x7528;<strong>&#x7B80;&#x77ED;</strong>&#x547D;&#x4EE4;&#x884C;&#x53C2;&#x6570;</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-encrypting-properties"></a></p>
<h3 id="246&#x3001;&#x52A0;&#x5BC6;&#x5C5E;&#x6027;">24.6&#x3001;&#x52A0;&#x5BC6;&#x5C5E;&#x6027;</h3>
<p>Spring Boot &#x6CA1;&#x6709;&#x4E3A;&#x52A0;&#x5BC6;&#x5C5E;&#x6027;&#x503C;&#x63D0;&#x4F9B;&#x4EFB;&#x4F55;&#x5185;&#x7F6E;&#x652F;&#x6301;&#xFF0C;&#x7136;&#x800C;&#xFF0C;&#x5B83;&#x63D0;&#x4F9B;&#x4E86;&#x4FEE;&#x6539; Spring <code>Environment</code> &#x5305;&#x542B;&#x7684;&#x503C;&#x6240;&#x5FC5;&#x9700;&#x7684;&#x94A9;&#x5B50;&#x3002;<code>EnvironmentPostProcessor</code> &#x63A5;&#x53E3;&#x5141;&#x8BB8;&#x60A8;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x542F;&#x52A8;&#x4E4B;&#x524D;&#x64CD;&#x4F5C; <code>Environment</code>&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x89C1;<a href="how-to.md#howto-customize-the-environment-or-application-context">&#x7B2C; 76.3 &#x7AE0;&#x8282;&#xFF1A;&#x5728;&#x542F;&#x52A8;&#x524D;&#x81EA;&#x5B9A;&#x4E49; Environment &#x6216; ApplicationContext</a>&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x6B63;&#x5728;&#x5BFB;&#x627E;&#x4E00;&#x79CD;&#x53EF;&#x7528;&#x4E8E;&#x5B58;&#x50A8;&#x51ED;&#x636E;&#x548C;&#x5BC6;&#x7801;&#x7684;&#x5B89;&#x5168;&#x65B9;&#x6CD5;&#xFF0C;<a href="https://cloud.spring.io/spring-cloud-vault/" target="_blank">Spring Cloud Vault</a> &#x9879;&#x76EE;&#x652F;&#x6301;&#x5728; <a href="https://www.vaultproject.io/" target="_blank">HashiCorp Vault</a> &#x4E2D;&#x5B58;&#x50A8;&#x5916;&#x90E8;&#x5316;&#x914D;&#x7F6E;&#x3002;</p>
<p><a id="boot-features-external-config-yaml"></a></p>
<h3 id="247&#x3001;&#x4F7F;&#x7528;-yaml-&#x4EE3;&#x66FF;&#x5C5E;&#x6027;&#x6587;&#x4EF6;">24.7&#x3001;&#x4F7F;&#x7528; YAML &#x4EE3;&#x66FF;&#x5C5E;&#x6027;&#x6587;&#x4EF6;</h3>
<p><a href="http://yaml.org/" target="_blank">YAML</a> &#x662F; JSON &#x7684;&#x8D85;&#x96C6;&#xFF0C;&#x662F;&#x4E00;&#x4E2A;&#x53EF;&#x7528;&#x4E8E;&#x6307;&#x5B9A;&#x5C42;&#x7EA7;&#x914D;&#x7F6E;&#x6570;&#x636E;&#x7684;&#x4FBF;&#x6377;&#x683C;&#x5F0F;&#x3002;&#x53EA;&#x8981;&#x5728; classpath &#x4E0A;&#x6709; <a href="http://www.snakeyaml.org/" target="_blank">SnakeYAML</a> &#x5E93;&#xFF0C;<code>SpringApplication</code> &#x7C7B;&#x5C31;&#x4F1A;&#x81EA;&#x52A8;&#x652F;&#x6301; YAML &#x4F5C;&#x4E3A;&#x5C5E;&#x6027;&#x6587;&#x4EF6;&#xFF08;properties&#xFF09;&#x7684;&#x66FF;&#x4EE3;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x4F7F;&#x7528; <strong>starter</strong>&#xFF0C;&#x5219; <code>spring-boot-starter</code> &#x4F1A;&#x81EA;&#x52A8;&#x63D0;&#x4F9B; SnakeYAML&#x3002;</p>
</blockquote>
<p><a id="boot-features-external-config-loading-yaml"></a></p>
<h4 id="2471&#x3001;&#x52A0;&#x8F7D;-yaml">24.7.1&#x3001;&#x52A0;&#x8F7D; YAML</h4>
<p>Spring Framework &#x63D0;&#x4F9B;&#x4E86;&#x4E24;&#x4E2A;&#x4FBF;&#x6377;&#x7C7B;&#xFF0C;&#x53EF;&#x7528;&#x4E8E;&#x52A0;&#x8F7D; YAML &#x6587;&#x6863;&#x3002;<code>YamlPropertiesFactoryBean</code> &#x5C06; YAML &#x52A0;&#x8F7D;&#x4E3A; <code>Properties</code>&#xFF0C;<code>YamlMapFactoryBean</code> &#x5C06; YAML &#x52A0;&#x8F7D;&#x4E3A; <code>Map</code>&#x3002;</p>
<p>&#x4F8B;&#x5982;&#x4EE5;&#x4E0B; YAML &#x6587;&#x6863;&#xFF1A;</p>
<pre class="language-"><code class="lang-yaml"><span class="token key atrule">environments</span><span class="token punctuation">:</span>
  <span class="token key atrule">dev</span><span class="token punctuation">:</span>
    <span class="token key atrule">url</span><span class="token punctuation">:</span> http<span class="token punctuation">:</span>//dev.example.com
    <span class="token key atrule">name</span><span class="token punctuation">:</span> Developer Setup
  <span class="token key atrule">prod</span><span class="token punctuation">:</span>
    <span class="token key atrule">url</span><span class="token punctuation">:</span> http<span class="token punctuation">:</span>//another.example.com
    <span class="token key atrule">name</span><span class="token punctuation">:</span> My Cool App
</code></pre>
<p>&#x524D;&#x9762;&#x7684;&#x793A;&#x4F8B;&#x5C06;&#x8F6C;&#x6362;&#x4E3A;&#x4EE5;&#x4E0B;&#x5C5E;&#x6027;&#xFF08;properties&#xFF09;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">environments.dev.url</span><span class="token attr-value"><span class="token punctuation">=</span>http://dev.example.com</span>
<span class="token constant">environments.dev.name</span><span class="token attr-value"><span class="token punctuation">=</span>Developer Setup</span>
<span class="token constant">environments.prod.url</span><span class="token attr-value"><span class="token punctuation">=</span>http://another.example.com</span>
<span class="token constant">environments.prod.name</span><span class="token attr-value"><span class="token punctuation">=</span>My Cool App</span>
</code></pre>
<p>YAML &#x5217;&#x8868;&#x8868;&#x793A;&#x5E26;&#x6709; <code>[index]</code> &#x4E0B;&#x6807;&#x5F15;&#x7528;&#x7684;&#x5C5E;&#x6027;&#x952E;&#x3002;&#x4F8B;&#x5982;&#x4EE5;&#x4E0B; YAML&#xFF1A;</p>
<pre class="language-"><code class="lang-yaml"><span class="token key atrule">my</span><span class="token punctuation">:</span>
<span class="token key atrule">servers</span><span class="token punctuation">:</span>
  <span class="token punctuation">-</span> dev.example.com
  <span class="token punctuation">-</span> another.example.com
</code></pre>
<p>&#x4EE5;&#x4E0A;&#x793A;&#x4F8B;&#x5C06;&#x8F6C;&#x6210;&#x4EE5;&#x4E0B;&#x5C5E;&#x6027;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">my.servers[0]</span><span class="token attr-value"><span class="token punctuation">=</span>dev.example.com</span>
<span class="token constant">my.servers[1]</span><span class="token attr-value"><span class="token punctuation">=</span>another.example.com</span>
</code></pre>
<p>&#x8981;&#x4F7F;&#x7528; Spring Boot &#x7684; <code>Binder</code> &#x5DE5;&#x5177;&#x6765;&#x7ED1;&#x5B9A;&#x8FD9;&#x6837;&#x914D;&#x7F6E;&#x5230;&#x5C5E;&#x6027;&#xFF08;&#x8FD9;&#x662F; <code>@ConfigurationProperties</code> &#x6240;&#x505A;&#x7684;&#xFF09;&#xFF0C;&#x4F60;&#x9700;&#x8981;&#x5728;&#x76EE;&#x6807; bean &#x4E2D;&#x6709;&#x4E00;&#x4E2A; <code>java.util.List</code>&#xFF08;&#x6216; <code>Set</code>&#xFF09;&#x7C7B;&#x578B;&#x7684;&#x5C5E;&#x6027;&#xFF0C;&#x4F60;&#x9700;&#x8981;&#x4E3A;&#x5176;&#x63D0;&#x4F9B;&#x4E00;&#x4E2A; setter &#x6216;&#x8005;&#x4F7F;&#x7528;&#x53EF;&#x53D8;&#x503C;&#x521D;&#x59CB;&#x5316;&#x5B83;&#x3002; &#x4F8B;&#x5982;&#xFF0C;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x5C06;&#x4E0A;&#x8FF0;&#x7684;&#x914D;&#x7F6E;&#x4E0E;&#x5C5E;&#x6027;&#x7ED1;&#x5B9A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix<span class="token operator">=</span><span class="token string">&quot;my&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Config</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> servers <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> <span class="token function">getServers</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>servers<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-external-config-exposing-yaml-to-spring"></a></p>
<h4 id="2472&#x3001;&#x5728;-spring-environment-&#x4E2D;&#x5C06;-yaml-&#x66B4;&#x9732;&#x4E3A;&#x5C5E;&#x6027;">24.7.2&#x3001;&#x5728; Spring Environment &#x4E2D;&#x5C06; YAML &#x66B4;&#x9732;&#x4E3A;&#x5C5E;&#x6027;</h4>
<p><code>YamlPropertySourceLoader</code> &#x7C7B;&#x53EF;&#x7528;&#x4E8E;&#x5728; Spring <code>Environment</code> &#x4E2D;&#x5C06; YAML &#x66B4;&#x9732;&#x4E3A; <code>PropertySource</code>&#x3002;&#x8FD9;&#x6837;&#x505A;&#x53EF;&#x4EE5;&#x8BA9;&#x60A8;&#x4F7F;&#x7528;&#x5E26;&#x5360;&#x4F4D;&#x7B26;&#x8BED;&#x6CD5;&#x7684; <code>@Value</code> &#x6CE8;&#x89E3;&#x6765;&#x8BBF;&#x95EE; YAML &#x5C5E;&#x6027;&#x3002;</p>
<p><a id="boot-features-external-config-multi-profile-yaml"></a></p>
<h4 id="2473&#x3001;&#x591A;-profile-yaml-&#x6587;&#x6863;">24.7.3&#x3001;&#x591A; profile YAML &#x6587;&#x6863;</h4>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.profiles</code> key &#x5728;&#x5355;&#x4E2A;&#x6587;&#x4EF6;&#x4E2D;&#x6307;&#x5B9A;&#x591A;&#x4E2A;&#x7279;&#x5B9A; profile &#x7684; YAML &#x6587;&#x6863;&#xFF0C;&#x4EE5;&#x6307;&#x793A;&#x6587;&#x6863;&#x4F55;&#x65F6;&#x5E94;&#x7528;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-yaml"><span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">address</span><span class="token punctuation">:</span> 192.168.1.100
<span class="token punctuation">---</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span> development
<span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">address</span><span class="token punctuation">:</span> 127.0.0.1
<span class="token punctuation">---</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span> production &amp; eu<span class="token punctuation">-</span>central
<span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">address</span><span class="token punctuation">:</span> 192.168.1.120
</code></pre>
<p>&#x5728;&#x524D;&#x9762;&#x793A;&#x4F8B;&#x4E2D;&#xFF0C;&#x5982;&#x679C; <code>development</code> profile &#x5904;&#x4E8E;&#x6FC0;&#x6D3B;&#x72B6;&#x6001;&#xFF0C;&#x5219; <code>server.address</code> &#x5C5E;&#x6027;&#x5F97;&#x503C;&#x4E3A; <code>127.0.0.1</code>&#x3002; &#x540C;&#x6837;&#xFF0C;&#x5982;&#x679C; <code>production</code> &#x548C; <code>eu-central</code> profile &#x5904;&#x4E8E;&#x6FC0;&#x6D3B;&#x72B6;&#x6001;&#xFF0C;&#x5219; <code>server.address</code> &#x5C5E;&#x6027;&#x7684;&#x503C;&#x4E3A; <code>192.168.1.120</code>&#x3002;&#x5982;&#x679C;&#x672A;&#x6FC0;&#x6D3B; <code>development</code>&#x3001;<code>production</code> &#x6216; <code>eu-central</code> profile&#xFF0C;&#x5219;&#x8BE5;&#x5C5E;&#x6027;&#x7684;&#x503C;&#x4E3A; <code>192.168.1.100</code>&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x56E0;&#x6B64;&#xFF0C;<code>spring.profiles</code> &#x53EF;&#x4EE5;&#x5305;&#x542B;&#x4E00;&#x4E2A;&#x7B80;&#x5355;&#x7684; profile &#x540D;&#x79F0;&#xFF08;&#x4F8B;&#x5982; <code>production</code>&#xFF09;&#x6216;&#x4E00;&#x4E2A; profile &#x8868;&#x8FBE;&#x5F0F;&#x3002;profile &#x8868;&#x8FBE;&#x5F0F;&#x5141;&#x8BB8;&#x8868;&#x8FBE;&#x66F4;&#x590D;&#x6742;&#x7684; profile &#x903B;&#x8F91;&#xFF0C;&#x4F8B;&#x5982; <code>production &amp; (eu-central | eu-west)</code>&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x67E5;&#x9605;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#beans-definition-profiles-java" target="_blank">&#x53C2;&#x8003;&#x6307;&#x5357;</a>&#x3002;</p>
</blockquote>
<p>&#x5982;&#x679C;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E0A;&#x4E0B;&#x6587;&#x542F;&#x52A8;&#x65F6;&#x6CA1;&#x6709;&#x663E;&#x5F0F;&#x6FC0;&#x6D3B;&#xFF0C;&#x5219;&#x6FC0;&#x6D3B;&#x9ED8;&#x8BA4; profile&#x3002;&#x56E0;&#x6B64;&#xFF0C;&#x5728;&#x4EE5;&#x4E0B; YAML &#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x4E3A; <code>spring.security.user.password</code> &#x8BBE;&#x7F6E;&#x4E86;&#x4E00;&#x4E2A;&#x503C;&#xFF0C;&#x8BE5;&#x503C;<strong>&#x4EC5;</strong>&#x5728; <code>default</code> profile &#x4E2D;&#x53EF;&#x7528;&#xFF1A;</p>
<pre class="language-"><code class="lang-yaml"><span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8000</span>
<span class="token punctuation">---</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span> default
  <span class="token key atrule">security</span><span class="token punctuation">:</span>
    <span class="token key atrule">user</span><span class="token punctuation">:</span>
      <span class="token key atrule">password</span><span class="token punctuation">:</span> weak
</code></pre>
<p>&#x7136;&#x800C;&#xFF0C;&#x5728;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x4E2D;&#xFF0C;&#x59CB;&#x7EC8;&#x8BBE;&#x7F6E;&#x5BC6;&#x7801;&#xFF0C;&#x56E0;&#x4E3A;&#x5B83;&#x672A;&#x9644;&#x52A0;&#x5230;&#x4EFB;&#x4F55; profile&#xFF0C;&#x5982;&#x679C;&#x9700;&#x8981;&#x66F4;&#x6539;&#xFF0C;&#x5FC5;&#x987B;&#x5728;&#x6240;&#x6709;&#x5176;&#x4ED6; profile &#x4E2D;&#x663E;&#x5F0F;&#x91CD;&#x7F6E;&#xFF1A;</p>
<pre class="language-"><code class="lang-yaml"><span class="token key atrule">server</span><span class="token punctuation">:</span>
  <span class="token key atrule">port</span><span class="token punctuation">:</span> <span class="token number">8000</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">security</span><span class="token punctuation">:</span>
    <span class="token key atrule">user</span><span class="token punctuation">:</span>
      <span class="token key atrule">password</span><span class="token punctuation">:</span> weak
</code></pre>
<p>&#x4F7F;&#x7528; <code>spring.profiles</code> &#x5143;&#x7D20;&#x6765;&#x6307;&#x5B9A; Spring profile &#x53EF;&#x4EE5;&#x9009;&#x62E9;&#x901A;&#x8FC7;&#x4F7F;&#x7528; <code>!</code> &#x5B57;&#x7B26;&#x6765;&#x53D6;&#x53CD;&#xFF08;&#x5426;&#x5B9A;&#xFF09;&#x3002;&#x5982;&#x679C;&#x4E3A;&#x5355;&#x4E2A;&#x6587;&#x6863;&#x6307;&#x5B9A;&#x4E86;&#x5426;&#x5B9A;&#x548C;&#x975E;&#x5426;&#x5B9A;&#x7684; profile&#xFF0C;&#x5219;&#x81F3;&#x5C11;&#x4E00;&#x4E2A;&#x975E;&#x5426;&#x5B9A;&#x7684; profile &#x5FC5;&#x987B;&#x5339;&#x914D;&#xFF0C;&#x6CA1;&#x6709;&#x5426;&#x5B9A;&#x7684; profile &#x53EF;&#x4EE5;&#x5339;&#x914D;&#x3002;</p>
<p><a id="boot-features-external-config-yaml-shortcomings"></a></p>
<h4 id="2474&#x3001;yaml-&#x7684;&#x7F3A;&#x70B9;">24.7.4&#x3001;YAML &#x7684;&#x7F3A;&#x70B9;</h4>
<p>&#x65E0;&#x6CD5;&#x4F7F;&#x7528; <code>@PropertySource</code> &#x6CE8;&#x89E3;&#x52A0;&#x8F7D; YAML &#x6587;&#x4EF6;&#x3002;&#x56E0;&#x6B64;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x4EE5;&#x8FD9;&#x79CD;&#x65B9;&#x5F0F;&#x52A0;&#x8F7D;&#x503C;&#xFF0C;&#x8BF7;&#x4F7F;&#x7528;&#x5C5E;&#x6027;&#x6587;&#x4EF6;&#xFF08;properties&#xFF09;&#x3002;</p>
<p><a id="boot-features-external-config-typesafe-configuration-properties"></a></p>
<h3 id="248&#x3001;&#x7C7B;&#x578B;&#x5B89;&#x5168;&#x7684;&#x914D;&#x7F6E;&#x5C5E;&#x6027;">24.8&#x3001;&#x7C7B;&#x578B;&#x5B89;&#x5168;&#x7684;&#x914D;&#x7F6E;&#x5C5E;&#x6027;</h3>
<p>&#x4F7F;&#x7528; <code>@Value(&quot;${property}&quot;)</code> &#x6CE8;&#x89E3;&#x6765;&#x6CE8;&#x5165;&#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x6709;&#x65F6;&#x4F1A;&#x5F88;&#x9EBB;&#x70E6;&#xFF0C;&#x7279;&#x522B;&#x662F;&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528;&#x4E86;&#x591A;&#x4E2A;&#x5C5E;&#x6027;&#x6216;&#x8005;&#x60A8;&#x7684;&#x6570;&#x636E;&#x672C;&#x8D28;&#x4E0A;&#x662F;&#x5206;&#x5C42;&#x7ED3;&#x6784;&#x3002;Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x53E6;&#x4E00;&#x79CD;&#x4F7F;&#x7528;&#x5C5E;&#x6027;&#x7684;&#x65B9;&#x6CD5;&#xFF0C;&#x8BE5;&#x65B9;&#x6CD5;&#x4F7F;&#x7528;&#x5F3A;&#x7C7B;&#x578B;&#x7684; bean &#x6765;&#x7BA1;&#x7406;&#x548C;&#x9A8C;&#x8BC1;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x914D;&#x7F6E;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>example</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>net</span><span class="token punctuation">.</span><span class="token class-name">InetAddress</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util</span><span class="token punctuation">.</span><span class="token class-name">ArrayList</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util</span><span class="token punctuation">.</span><span class="token class-name">Collections</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util</span><span class="token punctuation">.</span><span class="token class-name">List</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>context<span class="token punctuation">.</span>properties</span><span class="token punctuation">.</span><span class="token class-name">ConfigurationProperties</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span><span class="token string">&quot;acme&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AcmeProperties</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">boolean</span> enabled<span class="token punctuation">;</span>

    <span class="token keyword">private</span> <span class="token class-name">InetAddress</span> remoteAddress<span class="token punctuation">;</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">Security</span> security <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Security</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">isEnabled</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setEnabled</span><span class="token punctuation">(</span><span class="token keyword">boolean</span> enabled<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">InetAddress</span> <span class="token function">getRemoteAddress</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setRemoteAddress</span><span class="token punctuation">(</span><span class="token class-name">InetAddress</span> remoteAddress<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">Security</span> <span class="token function">getSecurity</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">Security</span> <span class="token punctuation">{</span>

        <span class="token keyword">private</span> <span class="token class-name">String</span> username<span class="token punctuation">;</span>

        <span class="token keyword">private</span> <span class="token class-name">String</span> password<span class="token punctuation">;</span>

        <span class="token keyword">private</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> roles <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token class-name">Collections</span><span class="token punctuation">.</span><span class="token function">singleton</span><span class="token punctuation">(</span><span class="token string">&quot;USER&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getUsername</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

        <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setUsername</span><span class="token punctuation">(</span><span class="token class-name">String</span> username<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

        <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getPassword</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

        <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setPassword</span><span class="token punctuation">(</span><span class="token class-name">String</span> password<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

        <span class="token keyword">public</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> <span class="token function">getRoles</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

        <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setRoles</span><span class="token punctuation">(</span><span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> roles<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<p>&#x524D;&#x9762;&#x7684; POJO &#x5B9A;&#x4E49;&#x4E86;&#x4EE5;&#x4E0B;&#x5C5E;&#x6027;&#xFF1A;</p>
<ul>
<li><code>acme.enabled</code>&#xFF0C;&#x9ED8;&#x8BA4;&#x503C;&#x4E3A; <code>false</code>&#x3002;</li>
<li><code>acme.remote-address</code>&#xFF0C;&#x53EF;&#x4EE5;&#x4ECE; String &#x5F3A;&#x5236;&#x8F6C;&#x6362;&#x7684;&#x7C7B;&#x578B;&#x3002;</li>
<li><code>acme.security.username</code>&#xFF0C;&#x5185;&#x5D4C;&#x4E00;&#x4E2A; <strong>security</strong> &#x5BF9;&#x8C61;&#xFF0C;&#x5176;&#x540D;&#x79F0;&#x7531;&#x5C5E;&#x6027;&#x540D;&#x79F0;&#x51B3;&#x5B9A;&#x3002;&#x7279;&#x522B;&#x662F;&#xFF0C;&#x8FD4;&#x56DE;&#x7C7B;&#x578B;&#x6839;&#x672C;&#x6CA1;&#x6709;&#x4F7F;&#x7528;&#xFF0C;&#x53EF;&#x80FD;&#x662F; <code>SecurityProperties</code>&#x3002;</li>
<li><code>acme.security.password</code>&#x3002;</li>
<li><code>acme.security.roles</code>&#xFF0C;String &#x96C6;&#x5408;&#x3002;</li>
</ul>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>

getter &#x548C; setter &#x901A;&#x5E38;&#x662F;&#x5FC5;&#x9700;&#x7684;&#xFF0C;&#x56E0;&#x4E3A;&#x7ED1;&#x5B9A;&#x662F;&#x901A;&#x8FC7;&#x6807;&#x51C6;&#x7684; Java Bean &#x5C5E;&#x6027;&#x63CF;&#x8FF0;&#x7B26;&#x6765;&#x5B8C;&#x6210;&#xFF0C;&#x5C31;&#x50CF;&#x5728; Spring MVC &#x4E2D;&#x4E00;&#x6837;&#x3002;&#x4EE5;&#x4E0B;&#x60C5;&#x51B5;&#x53EF;&#x4EE5;&#x7701;&#x7565; setter&#xFF1A;

- Map&#xFF0C;&#x53EA;&#x8981;&#x5B83;&#x4EEC;&#x8981;&#x521D;&#x59CB;&#x5316;&#xFF0C;&#x5C31;&#x9700;&#x8981;&#x4E00;&#x4E2A; getter &#x4F46;&#x4E0D;&#x4E00;&#x5B9A;&#x9700;&#x8981;setter&#xFF0C;&#x56E0;&#x4E3A;&#x5B83;&#x4EEC;&#x53EF;&#x4EE5;&#x88AB; binder &#x4FEE;&#x6539;&#x3002;
- &#x96C6;&#x5408;&#x548C;&#x6570;&#x7EC4;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4E00;&#x4E2A;&#x7D22;&#x5F15;&#xFF08;&#x901A;&#x5E38;&#x4F7F;&#x7528; YAML&#xFF09;&#x6216;&#x4F7F;&#x7528;&#x5355;&#x4E2A;&#x9017;&#x53F7;&#x5206;&#x9694;&#x503C;&#xFF08;&#x5C5E;&#x6027;&#xFF09;&#x8FDB;&#x884C;&#x8BBF;&#x95EE;&#x3002;&#x6700;&#x540E;&#x4E00;&#x79CD;&#x60C5;&#x51B5;&#x5FC5;&#x987B;&#x4F7F;&#x7528; setter&#x3002;&#x6211;&#x4EEC;&#x5EFA;&#x8BAE;&#x59CB;&#x7EC8;&#x4E3A;&#x6B64;&#x7C7B;&#x578B;&#x6DFB;&#x52A0; setter&#x3002;&#x5982;&#x679C;&#x521D;&#x59CB;&#x5316;&#x96C6;&#x5408;&#xFF0C;&#x8BF7;&#x786E;&#x4FDD;&#x5B83;&#x662F;&#x53EF;&#x53D8;&#x7684;&#xFF08;&#x5982;&#x4E0A;&#x4F8B;&#x6240;&#x793A;&#xFF09;&#x3002;
- &#x5982;&#x679C;&#x521D;&#x59CB;&#x5316;&#x5D4C;&#x5957;&#x7684; POJO &#x5C5E;&#x6027;&#xFF08;&#x5982;&#x524D;&#x9762;&#x793A;&#x4F8B;&#x4E2D;&#x7684; `Security` &#x5B57;&#x6BB5;&#xFF09;&#xFF0C;&#x5219;&#x4E0D;&#x9700;&#x8981; setter&#x3002;&#x5982;&#x679C;&#x60A8;&#x5E0C;&#x671B; binder &#x4F7F;&#x7528;&#x5176;&#x9ED8;&#x8BA4;&#x6784;&#x9020;&#x51FD;&#x6570;&#x52A8;&#x6001;&#x521B;&#x5EFA;&#x5B9E;&#x4F8B;&#xFF0C;&#x5219;&#x9700;&#x8981;&#x4E00;&#x4E2A; setter&#x3002;

&#x6709;&#x4E9B;&#x4EBA;&#x53EF;&#x80FD;&#x4F1A;&#x4F7F;&#x7528; Project Lombok &#x6765;&#x81EA;&#x52A8;&#x751F;&#x6210; getter &#x548C; setter&#x3002;&#x8BF7;&#x786E;&#x4FDD; Lombok &#x4E0D;&#x4E3A;&#x6B64;&#x7C7B;&#x578B;&#x751F;&#x6210;&#x4EFB;&#x4F55;&#x7279;&#x5B9A;&#x6784;&#x9020;&#x51FD;&#x6570;&#xFF0C;&#x56E0;&#x4E3A;&#x5BB9;&#x5668;&#x4F1A;&#x81EA;&#x52A8;&#x4F7F;&#x7528;&#x5B83;&#x6765;&#x5B9E;&#x4F8B;&#x5316;&#x5BF9;&#x8C61;&#x3002;

&#x6700;&#x540E;&#xFF0C;&#x8003;&#x8651;&#x5230;&#x6807;&#x51C6; Java Bean &#x5C5E;&#x6027;&#xFF0C;&#x4E0D;&#x652F;&#x6301;&#x5BF9;&#x9759;&#x6001;&#x5C5E;&#x6027;&#x7684;&#x7ED1;&#x5B9A;&#x3002;

</blockquote>

<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x53E6;&#x8BF7;&#x53C2;&#x9605; <a href="#boot-features-external-config-vs-value">@Value &#x548C; @ConfigurationProperties &#x4E4B;&#x95F4;&#x7684;&#x5DEE;&#x5F02;</a>&#x3002;</p>
</blockquote>
<p>&#x60A8;&#x8FD8;&#x9700;&#x8981;&#x5217;&#x51FA;&#x8981;&#x5728; <code>@EnableConfigurationProperties</code> &#x6CE8;&#x89E3;&#x4E2D;&#x6CE8;&#x518C;&#x7684;&#x5C5E;&#x6027;&#x7C7B;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@EnableConfigurationProperties</span><span class="token punctuation">(</span><span class="token class-name">AcmeProperties</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyConfiguration</span> <span class="token punctuation">{</span>
<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>

&#x5F53;&#x4EE5;&#x8FD9;&#x79CD;&#x65B9;&#x5F0F;&#x6CE8;&#x518C; `@ConfigurationProperties` bean &#x65F6;&#xFF0C;bean &#x5177;&#x6709;&#x4E00;&#x4E2A;&#x56FA;&#x5B9A;&#x683C;&#x5F0F;&#x7684;&#x540D;&#x79F0;&#xFF1A;`<prefix>-<fqn>`&#xFF0C;&#x5176;&#x4E2D; `<prefix>` &#x662F; `@ConfigurationProperties` &#x6CE8;&#x89E3;&#x4E2D;&#x6307;&#x5B9A;&#x7684;&#x73AF;&#x5883; key &#x524D;&#x7F00;&#xFF0C;`<fqn>` &#x662F; bean &#x7684;&#x5B8C;&#x5168;&#x9650;&#x5B9A;&#x7C7B;&#x540D;&#x3002;&#x5982;&#x679C;&#x6CE8;&#x89E3;&#x672A;&#x63D0;&#x4F9B;&#x4EFB;&#x4F55;&#x524D;&#x7F00;&#xFF0C;&#x5219;&#x4EC5;&#x4F7F;&#x7528; bean &#x7684;&#x5B8C;&#x5168;&#x9650;&#x5B9A;&#x7C7B;&#x540D;&#x3002;

&#x4E0A;&#x9762;&#x793A;&#x4F8B;&#x4E2D;&#x7684; bean &#x540D;&#x79F0;&#x4E3A; `acme-com.example.AcmeProperties`&#x3002;

</fqn></prefix></fqn></prefix></blockquote>

<p>&#x5373;&#x4F7F;&#x524D;&#x9762;&#x7684;&#x914D;&#x7F6E;&#x4E3A; <code>AcmeProperties</code> &#x521B;&#x5EFA;&#x4E86;&#x4E00;&#x4E2A; bean&#xFF0C;&#x6211;&#x4EEC;&#x4E5F;&#x5EFA;&#x8BAE; <code>@ConfigurationProperties</code> &#x53EA;&#x5904;&#x7406;&#x73AF;&#x5883;&#xFF08;environment&#xFF09;&#xFF0C;&#x7279;&#x522B;&#x662F;&#x4E0D;&#x8981;&#x4ECE;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x6CE8;&#x5165;&#x5176;&#x4ED6; bean&#x3002;&#x8BDD;&#x867D;&#x5982;&#x6B64;&#xFF0C;<code>@EnableConfigurationProperties</code> &#x6CE8;&#x89E3;&#x4E5F;&#x4F1A;&#x81EA;&#x52A8;&#x5E94;&#x7528;&#x5230;&#x60A8;&#x7684;&#x9879;&#x76EE;&#xFF0C;&#x4EE5;&#x4FBF;&#x4ECE; <code>Environment</code> &#x914D;&#x7F6E;&#x4F7F;&#x7528;&#x4E86; <code>@ConfigurationProperties</code> &#x6CE8;&#x89E3;&#x7684;&#x6240;&#x6709;<strong>&#x73B0;&#x6709;</strong>&#x7684; bean&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x786E;&#x4FDD; <code>AcmeProperties</code> &#x5DF2;&#x7ECF;&#x662F;&#x4E00;&#x4E2A; bean &#x6765;&#x5FEB;&#x6377;&#x751F;&#x6210; <code>MyConfiguration</code>&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix<span class="token operator">=</span><span class="token string">&quot;acme&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AcmeProperties</span> <span class="token punctuation">{</span>

    <span class="token comment">// ... see the preceding example</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x8FD9;&#x79CD;&#x914D;&#x7F6E;&#x98CE;&#x683C;&#x7279;&#x522B;&#x9002;&#x7528;&#x4E8E; <code>SpringApplication</code> &#x5916;&#x90E8; YAML &#x914D;&#x7F6E;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-yaml"><span class="token comment"># application.yml</span>

<span class="token key atrule">acme</span><span class="token punctuation">:</span>
    <span class="token key atrule">remote-address</span><span class="token punctuation">:</span> 192.168.1.1
    <span class="token key atrule">security</span><span class="token punctuation">:</span>
        <span class="token key atrule">username</span><span class="token punctuation">:</span> admin
        <span class="token key atrule">roles</span><span class="token punctuation">:</span>
          <span class="token punctuation">-</span> USER
          <span class="token punctuation">-</span> ADMIN

<span class="token comment"># additional configuration as required</span>
</code></pre>
<p>&#x8981;&#x4F7F;&#x7528; <code>@ConfigurationProperties</code> bean&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4E0E;&#x5176;&#x4ED6; bean &#x76F8;&#x540C;&#x7684;&#x65B9;&#x5F0F;&#x6CE8;&#x5165;&#x5B83;&#x4EEC;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Service</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyService</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">AcmeProperties</span> properties<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyService</span><span class="token punctuation">(</span><span class="token class-name">AcmeProperties</span> properties<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>properties <span class="token operator">=</span> properties<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

     <span class="token comment">//...</span>

    <span class="token annotation punctuation">@PostConstruct</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">openConnection</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">Server</span> server <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Server</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span>properties<span class="token punctuation">.</span><span class="token function">getRemoteAddress</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x4F7F;&#x7528; <code>@ConfigurationProperties</code> &#x8FD8;&#x53EF;&#x4EE5;&#x751F;&#x6210;&#x5143;&#x6570;&#x636E;&#x6587;&#x4EF6;&#xFF0C;IDE &#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8FD9;&#x4E9B;&#x6587;&#x4EF6;&#x6765;&#x4E3A;&#x60A8;&#x81EA;&#x5DF1;&#x7684; key &#x63D0;&#x4F9B;&#x81EA;&#x52A8;&#x5B8C;&#x6210;&#x529F;&#x80FD;&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605;<a href="https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#configuration-metadata" target="_blank">&#x9644;&#x5F55; B&#xFF1A;&#x914D;&#x7F6E;&#x5143;&#x6570;&#x636E;</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-external-config-3rd-party-configuration"></a></p>
<h4 id="2481&#x3001;&#x7B2C;&#x4E09;&#x65B9;&#x914D;&#x7F6E;">24.8.1&#x3001;&#x7B2C;&#x4E09;&#x65B9;&#x914D;&#x7F6E;</h4>
<p><code>@ConfigurationProperties</code> &#x9664;&#x4E86;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x6765;&#x6CE8;&#x89E3;&#x7C7B;&#x4E4B;&#x5916;&#xFF0C;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x5728;&#x516C;&#x5171;&#x7684; @Bean &#x65B9;&#x6CD5;&#x4E0A;&#x4F7F;&#x7528;&#x3002;&#x5F53;&#x60A8;&#x60F3;&#x8981;&#x5C06;&#x5C5E;&#x6027;&#x7ED1;&#x5B9A;&#x5230;&#x60A8;&#x638C;&#x63A7;&#x4E4B;&#x5916;&#x7684;&#x7B2C;&#x4E09;&#x65B9;&#x7EC4;&#x4EF6;&#x65F6;&#xFF0C;&#x8FD9;&#x6837;&#x505A;&#x7279;&#x522B;&#x6709;&#x7528;&#x3002;</p>
<p>&#x8981;&#x4F7F;&#x7528; <code>Environment</code> &#x5C5E;&#x6027;&#x914D;&#x7F6E; bean&#xFF0C;&#x8BF7;&#x5C06; <code>@ConfigurationProperties</code> &#x6DFB;&#x52A0;&#x5230; bean &#x6CE8;&#x518C;&#x4E0A;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix <span class="token operator">=</span> <span class="token string">&quot;another&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">AnotherComponent</span> <span class="token function">anotherComponent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
<span class="token punctuation">}</span>
</code></pre>
<p>&#x4F7F;&#x7528; <code>another</code> &#x524D;&#x7F00;&#x5B9A;&#x4E49;&#x7684;&#x6240;&#x6709;&#x5C5E;&#x6027;&#x90FD;&#x4F7F;&#x7528;&#x4E0E;&#x524D;&#x9762;&#x7684; <code>AcmeProperties</code> &#x793A;&#x4F8B;&#x7C7B;&#x4F3C;&#x7684;&#x65B9;&#x5F0F;&#x6620;&#x5C04;&#x5230; <code>AnotherComponent</code> bean&#x3002;</p>
<p><a id="boot-features-external-config-relaxed-binding"></a></p>
<h4 id="2482&#x3001;&#x5BBD;&#x677E;&#x7ED1;&#x5B9A;">24.8.2&#x3001;&#x5BBD;&#x677E;&#x7ED1;&#x5B9A;</h4>
<p>Spring Boot &#x4F7F;&#x7528;&#x4E00;&#x4E9B;&#x5BBD;&#x677E;&#x7684;&#x89C4;&#x5219;&#x5C06; <code>Environment</code> &#x5C5E;&#x6027;&#x7ED1;&#x5B9A;&#x5230; <code>@ConfigurationProperties</code> bean&#xFF0C;&#x56E0;&#x6B64; <code>Environment</code> &#x5C5E;&#x6027;&#x540D;&#x4E0D;&#x9700;&#x8981;&#x548C; bean &#x5C5E;&#x6027;&#x540D;&#x7CBE;&#x786E;&#x5339;&#x914D;&#x3002;&#x5E38;&#x89C1;&#x7684;&#x793A;&#x4F8B;&#x5305;&#x62EC;&#x4F7F;&#x7528;&#x4E86; <code>-</code> &#x7B26;&#x53F7;&#x5206;&#x5272;&#x7684;&#x73AF;&#x5883;&#x5C5E;&#x6027;&#xFF08;&#x4F8B;&#x5982;&#xFF0C;<code>context-path</code> &#x7ED1;&#x5B9A;&#x5230; <code>contextPath</code>&#xFF09;&#x548C;&#x5927;&#x5199;&#x73AF;&#x5883;&#x5C5E;&#x6027;&#xFF08;&#x4F8B;&#x5982;&#xFF0C;<code>PORT</code> &#x7ED1;&#x5B9A;&#x5230; <code>port</code>&#xFF09;&#x3002;</p>
<p>&#x5982;&#x4E0B; <code>@ConfigurationProperties</code> &#x7C7B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix<span class="token operator">=</span><span class="token string">&quot;acme.my-project.person&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">OwnerProperties</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token class-name">String</span> firstName<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getFirstName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>firstName<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setFirstName</span><span class="token punctuation">(</span><span class="token class-name">String</span> firstName<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>firstName <span class="token operator">=</span> firstName<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x5728;&#x4E0A;&#x8FF0;&#x793A;&#x4F8B;&#x4E2D;&#xFF0C;&#x540C;&#x6837;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4EE5;&#x4E0B;&#x5C5E;&#x6027;&#x540D;&#x79F0;&#xFF1A;</p>
<p><strong>&#x8868; 24.1&#x3001;&#x5BBD;&#x677E;&#x7ED1;&#x5B9A;</strong></p>
<table>
<thead>
<tr>
<th>&#x5C5E;&#x6027;</th>
<th>&#x63CF;&#x8FF0;</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>acme.my-project.person.first-name</code></td>
<td>Kebab &#x98CE;&#x683C;&#xFF08;&#x77ED;&#x6A2A;&#x7EBF;&#x547D;&#x540D;&#xFF09;&#xFF0C;&#x5EFA;&#x8BAE;&#x5728; <code>.properties</code> &#x548C; <code>.yml</code> &#x6587;&#x4EF6;&#x4E2D;&#x4F7F;&#x7528;&#x3002;</td>
</tr>
<tr>
<td><code>acme.myProject.person.firstName</code></td>
<td>&#x6807;&#x51C6;&#x9A7C;&#x5CF0;&#x5F0F;&#x98CE;&#x683C;&#x3002;</td>
</tr>
<tr>
<td><code>acme.my_project.person.first_name</code></td>
<td>&#x4E0B;&#x5212;&#x7EBF;&#x8868;&#x793A;&#x6CD5;&#xFF0C;<code>.properties</code> &#x548C; <code>.yaml</code> &#x6587;&#x4EF6;&#x4E2D;&#x7684;&#x53E6;&#x5916;&#x4E00;&#x79CD;&#x683C;&#x5F0F;&#x3002;</td>
</tr>
<tr>
<td><code>ACME_MYPROJECT_PERSON_FIRSTNAME</code></td>
<td>&#x5927;&#x5199;&#x98CE;&#x683C;&#xFF0C;&#x5F53;&#x4F7F;&#x7528;&#x7CFB;&#x7EDF;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#x65F6;&#x63A8;&#x8350;&#x4F7F;&#x7528;&#x8BE5;&#x98CE;&#x683C;&#x3002;</td>
</tr>
</tbody>
</table>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x6CE8;&#x89E3;&#x7684; <code>prefix</code> &#x503C;&#x5FC5;&#x987B;&#x662F; kebab (&#x77ED;&#x6A2A;&#x7EBF;&#x547D;&#x540D;)&#x98CE;&#x683C;&#xFF08;&#x5C0F;&#x5199;&#x5E76;&#x7528; <code>-</code> &#x5206;&#x9694;&#xFF0C;&#x4F8B;&#x5982; <code>acme.my-project.person</code>&#xFF09;&#x3002;</p>
</blockquote>
<p><strong>&#x8868; 24.2&#x3001;&#x6BCF;&#x79CD;&#x5C5E;&#x6027;&#x6E90;&#xFF08;property source&#xFF09;&#x7684;&#x5BBD;&#x677E;&#x7ED1;&#x5B9A;&#x89C4;&#x5219;</strong></p>
<table>
<thead>
<tr>
<th>&#x5C5E;&#x6027;&#x6E90;</th>
<th>&#x7B80;&#x5355;&#x7C7B;&#x578B;</th>
<th>&#x5217;&#x8868;&#x96C6;&#x5408;&#x7C7B;&#x578B;</th>
</tr>
</thead>
<tbody>
<tr>
<td>properties &#x6587;&#x4EF6;</td>
<td>&#x9A7C;&#x5CF0;&#x5F0F;&#x3001;&#x77ED;&#x6A2A;&#x7EBF;&#x5F0F;&#x6216;&#x4E0B;&#x5212;&#x7EBF;&#x5F0F;</td>
<td>&#x6807;&#x51C6;&#x5217;&#x8868;&#x8BED;&#x6CD5;&#x4F7F;&#x7528; <code>[]</code> &#x6216;&#x9017;&#x53F7;&#x5206;&#x9694;&#x503C;</td>
</tr>
<tr>
<td>YAML &#x6587;&#x4EF6;</td>
<td>&#x9A7C;&#x5CF0;&#x5F0F;&#x3001;&#x77ED;&#x6A2A;&#x7EBF;&#x5F0F;&#x6216;&#x8005;&#x4E0B;&#x5212;&#x7EBF;&#x5F0F;</td>
<td>&#x6807;&#x51C6; YAML &#x5217;&#x8868;&#x8BED;&#x6CD5;&#x6216;&#x8005;&#x9017;&#x53F7;&#x5206;&#x9694;&#x503C;</td>
</tr>
<tr>
<td>&#x73AF;&#x5883;&#x53D8;&#x91CF;</td>
<td>&#x5927;&#x5199;&#x5E76;&#x4E14;&#x4EE5;&#x4E0B;&#x5212;&#x7EBF;&#x4F5C;&#x4E3A;&#x5B9A;&#x754C;&#x7B26;&#xFF0C;<code>_</code> &#x4E0D;&#x80FD;&#x653E;&#x5728;&#x5C5E;&#x6027;&#x540D;&#x4E4B;&#x95F4;&#x4F7F;&#x7528;</td>
<td>&#x6570;&#x5B57;&#x503C;&#x4E24;&#x8FB9;&#x4F7F;&#x7528;&#x4E0B;&#x5212;&#x7EBF;&#x8FDE;&#x63A5;&#xFF0C;&#x4F8B;&#x5982; <code>MY_ACME_1_OTHER = my.acme[1].other</code></td>
</tr>
<tr>
<td>&#x7CFB;&#x7EDF;&#x5C5E;&#x6027;</td>
<td>&#x9A7C;&#x5CF0;&#x5F0F;&#x3001;&#x77ED;&#x6A2A;&#x7EBF;&#x5F0F;&#x6216;&#x8005;&#x4E0B;&#x5212;&#x7EBF;&#x5F0F;</td>
<td>&#x6807;&#x51C6;&#x5217;&#x8868;&#x8BED;&#x6CD5;&#x4F7F;&#x7528; <code>[]</code> &#x6216;&#x9017;&#x53F7;&#x5206;&#x9694;&#x503C;</td>
</tr>
</tbody>
</table>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6211;&#x4EEC;&#x5EFA;&#x8BAE;&#xFF0C;&#x5C5E;&#x6027;&#x5C3D;&#x53EF;&#x80FD;&#x4EE5;&#x5C0F;&#x5199;&#x7684;&#x77ED;&#x6A2A;&#x7EBF;&#x683C;&#x5F0F;&#x5B58;&#x50A8;&#xFF0C;&#x6BD4;&#x5982; <code>my.property-name=acme</code>&#x3002;</p>
</blockquote>
<p>&#x5F53;&#x7ED1;&#x5B9A;&#x5230; <code>Map</code> &#x5C5E;&#x6027;&#x65F6;&#xFF0C;&#x5982;&#x679C; key &#x5305;&#x542B;&#x9664;&#x5C0F;&#x5199;&#x5B57;&#x6BCD;&#x6570;&#x5B57;&#x5B57;&#x7B26;&#x6216; <code>-</code> &#x4EE5;&#x5916;&#x7684;&#x4EFB;&#x4F55;&#x5185;&#x5BB9;&#xFF0C;&#x5219;&#x9700;&#x8981;&#x4F7F;&#x7528;&#x62EC;&#x53F7;&#x8868;&#x793A;&#x6CD5;&#x6765;&#x4FDD;&#x7559;&#x539F;&#x59CB;&#x503C;&#x3002;&#x5982;&#x679C; key &#x6CA1;&#x6709;&#x4F7F;&#x7528; <code>[]</code> &#x5305;&#x88F9;&#xFF0C;&#x5219;&#x91CC;&#x9762;&#x7684;&#x4EFB;&#x4F55;&#x975E;&#x5B57;&#x6BCD;&#x6570;&#x5B57;&#x5B57;&#x7B26;&#x6216; <code>-</code> &#x7684;&#x5B57;&#x7B26;&#x90FD;&#x5C06;&#x88AB;&#x5220;&#x9664;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5C06;&#x4EE5;&#x4E0B;&#x5C5E;&#x6027;&#x7ED1;&#x5B9A;&#x5230;&#x4E00;&#x4E2A; <code>Map</code>&#xFF1A;</p>
<pre class="language-"><code class="lang-yaml"><span class="token key atrule">acme</span><span class="token punctuation">:</span>
  <span class="token key atrule">map</span><span class="token punctuation">:</span>
    &quot;<span class="token punctuation">[</span>/key1<span class="token punctuation">]</span>&quot;<span class="token punctuation">:</span> value1
    &quot;<span class="token punctuation">[</span>/key2<span class="token punctuation">]</span>&quot;<span class="token punctuation">:</span> value2
    <span class="token key atrule">/key3</span><span class="token punctuation">:</span> value3
</code></pre>
<p>&#x4E0A;&#x9762;&#x7684;&#x5C5E;&#x6027;&#x5C06;&#x7ED1;&#x5B9A;&#x5230;&#x4E00;&#x4E2A; <code>Map</code> &#x4E0A;&#xFF0C;&#x5176;&#x4E2D; <code>/key1</code>&#xFF0C;<code>/key2</code> &#x548C; <code>key3</code> &#x4F5C;&#x4E3A; map &#x7684; key&#x3002;</p>
<p><a id="boot-features-external-config-complex-type-merge"></a></p>
<h4 id="2483&#x3001;&#x5408;&#x5E76;&#x590D;&#x6742;&#x7C7B;&#x578B;">24.8.3&#x3001;&#x5408;&#x5E76;&#x590D;&#x6742;&#x7C7B;&#x578B;</h4>
<p>&#x5F53;&#x5217;&#x8868;&#x96C6;&#x5408;&#xFF08;list&#xFF09;&#x5728;&#x591A;&#x4E2A;&#x5730;&#x65B9;&#x914D;&#x7F6E;&#x65F6;&#xFF0C;&#x6574;&#x4E2A;&#x5217;&#x8868;&#x96C6;&#x5408;&#x5C06;&#x88AB;&#x66FF;&#x6362;&#x3002;</p>
<p>&#x4F8B;&#x5982;&#xFF0C;&#x5047;&#x8BBE;&#x5E26;&#x6709; <code>name</code> &#x548C; <code>description</code> &#x5C5E;&#x6027;&#x7684; <code>MyPojo</code> &#x5BF9;&#x8C61;&#x9ED8;&#x8BA4;&#x4E3A; <code>null</code>&#x3002;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x4E2D;&#xFF0C;<code>AcmeProperties</code> &#x66B4;&#x9732;&#x4E86;&#x4E00;&#x4E2A; <code>MyPojo</code> &#x5BF9;&#x8C61;&#x5217;&#x8868;&#x96C6;&#x5408;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span><span class="token string">&quot;acme&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AcmeProperties</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">MyPojo</span><span class="token punctuation">&gt;</span></span> list <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ArrayList</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">MyPojo</span><span class="token punctuation">&gt;</span></span> <span class="token function">getList</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>list<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x914D;&#x7F6E;&#x53EF;&#x4EE5;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre class="language-"><code class="lang-yaml"><span class="token key atrule">acme</span><span class="token punctuation">:</span>
  <span class="token key atrule">list</span><span class="token punctuation">:</span>
    <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> my name
      <span class="token key atrule">description</span><span class="token punctuation">:</span> my description
<span class="token punctuation">---</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span> dev
<span class="token key atrule">acme</span><span class="token punctuation">:</span>
  <span class="token key atrule">list</span><span class="token punctuation">:</span>
    <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> my another name
</code></pre>
<p>&#x5982;&#x679C; <code>dev</code> &#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x672A;&#x6FC0;&#x6D3B;&#xFF0C;&#x5219; <code>AcmeProperties.list</code> &#x53EA;&#x5305;&#x542B;&#x4E00;&#x6761; <code>MyPojo</code> &#x6761;&#x76EE;&#xFF0C;&#x5982;&#x4E4B;&#x524D;&#x6240;&#x8FF0;&#x3002;&#x4F46;&#x662F;&#xFF0C;&#x5982;&#x679C;&#x6FC0;&#x6D3B;&#x4E86; <code>dev</code> &#x914D;&#x7F6E;&#x6587;&#x4EF6;&#xFF0C;&#x5217;&#x8868;&#x96C6;&#x5408;&#x4ECD;&#x7136;&#x53EA;&#x5305;&#x542B;&#x4E00;&#x4E2A;&#x6761;&#x76EE;&#xFF08;<code>name</code> &#x5C5E;&#x6027;&#x503C;&#x4E3A; <code>my another name</code>&#xFF0C;<code>description</code> &#x4E3A; <code>null</code>&#xFF09;&#x3002;&#x6B64;&#x914D;&#x7F6E;&#x4E0D;&#x4F1A;&#x5411;&#x5217;&#x8868;&#x96C6;&#x5408;&#x4E2D;&#x6DFB;&#x52A0;&#x7B2C;&#x4E8C;&#x4E2A; <code>MyPojo</code> &#x5B9E;&#x4F8B;&#xFF0C;&#x4E5F;&#x4E0D;&#x4F1A;&#x5408;&#x5E76;&#x6761;&#x76EE;&#x3002;</p>
<p>&#x5728;&#x591A;&#x4E2A;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4E2D;&#x6307;&#x5B9A;&#x4E00;&#x4E2A; <code>List</code> &#x65F6;&#xFF0C;&#x6700;&#x9AD8;&#x4F18;&#x5148;&#x7EA7;&#xFF08;&#x5E76;&#x4E14;&#x53EA;&#x6709;&#x4E00;&#x4E2A;&#xFF09;&#x7684;&#x5217;&#x8868;&#x96C6;&#x5408;&#x5C06;&#x88AB;&#x4F7F;&#x7528;&#x3002;&#x53EF;&#x505A;&#x5982;&#x4E0B;&#x914D;&#x7F6E;&#xFF1A;</p>
<pre class="language-"><code class="lang-yaml"><span class="token key atrule">acme</span><span class="token punctuation">:</span>
  <span class="token key atrule">list</span><span class="token punctuation">:</span>
    <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> my name
      <span class="token key atrule">description</span><span class="token punctuation">:</span> my description
    <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> another name
      <span class="token key atrule">description</span><span class="token punctuation">:</span> another description
<span class="token punctuation">---</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span> dev
<span class="token key atrule">acme</span><span class="token punctuation">:</span>
  <span class="token key atrule">list</span><span class="token punctuation">:</span>
    <span class="token punctuation">-</span> <span class="token key atrule">name</span><span class="token punctuation">:</span> my another name
</code></pre>
<p>&#x5728;&#x524D;&#x9762;&#x793A;&#x4F8B;&#x4E2D;&#xFF0C;&#x5982;&#x679C; <code>dev</code> &#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x5904;&#x4E8E;&#x6D3B;&#x52A8;&#x72B6;&#x6001;&#xFF0C;&#x5219; <code>AcmeProperties.list</code> &#x5305;&#x542B;&#x4E00;&#x4E2A; <code>MyPojo</code> &#x6761;&#x76EE;&#xFF08;<code>name</code> &#x4E3A; <code>my another name</code>&#xFF0C;<code>description</code> &#x4E3A; <code>null</code>&#xFF09;&#x3002;&#x5BF9;&#x4E8E; YAML &#x800C;&#x8A00;&#xFF0C;&#x9017;&#x53F7;&#x5206;&#x9694;&#x7684;&#x5217;&#x8868;&#x548C;YAML &#x5217;&#x8868;&#x540C;&#x6837;&#x4F1A;&#x5B8C;&#x5168;&#x8986;&#x76D6;&#x5217;&#x8868;&#x96C6;&#x5408;&#x7684;&#x5185;&#x5BB9;&#x3002;</p>
<p>&#x5BF9;&#x4E8E; <code>Map</code> &#x5C5E;&#x6027;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x7ED1;&#x5B9A;&#x6765;&#x81EA;&#x591A;&#x4E2A;&#x6E90;&#x4E2D;&#x63D0;&#x53D6;&#x7684;&#x5C5E;&#x6027;&#x503C;&#x3002;&#x4F46;&#x662F;&#xFF0C;&#x5BF9;&#x4E8E;&#x591A;&#x4E2A;&#x6E90;&#x4E2D;&#x7684;&#x76F8;&#x540C;&#x5C5E;&#x6027;&#xFF0C;&#x5219;&#x4F7F;&#x7528;&#x9AD8;&#x4F18;&#x5148;&#x7EA7;&#x6700;&#x9AD8;&#x7684;&#x5C5E;&#x6027;&#x3002;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x4ECE; <code>AcmeProperties</code> &#x66B4;&#x9732;&#x4E86;&#x4E00;&#x4E2A; <code>Map<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>String,</span> <span class="token attr-name">MyPojo</span><span class="token punctuation">&gt;</span></span></code>&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span><span class="token string">&quot;acme&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AcmeProperties</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">MyPojo</span><span class="token punctuation">&gt;</span></span> map <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HashMap</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">MyPojo</span><span class="token punctuation">&gt;</span></span> <span class="token function">getMap</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>map<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x53EF;&#x4EE5;&#x8003;&#x8651;&#x4EE5;&#x4E0B;&#x914D;&#x7F6E;&#xFF1A;</p>
<pre class="language-"><code class="lang-yaml"><span class="token key atrule">acme</span><span class="token punctuation">:</span>
  <span class="token key atrule">map</span><span class="token punctuation">:</span>
    <span class="token key atrule">key1</span><span class="token punctuation">:</span>
      <span class="token key atrule">name</span><span class="token punctuation">:</span> my name 1
      <span class="token key atrule">description</span><span class="token punctuation">:</span> my description 1
<span class="token punctuation">---</span>
<span class="token key atrule">spring</span><span class="token punctuation">:</span>
  <span class="token key atrule">profiles</span><span class="token punctuation">:</span> dev
<span class="token key atrule">acme</span><span class="token punctuation">:</span>
  <span class="token key atrule">map</span><span class="token punctuation">:</span>
    <span class="token key atrule">key1</span><span class="token punctuation">:</span>
      <span class="token key atrule">name</span><span class="token punctuation">:</span> dev name 1
    <span class="token key atrule">key2</span><span class="token punctuation">:</span>
      <span class="token key atrule">name</span><span class="token punctuation">:</span> dev name 2
      <span class="token key atrule">description</span><span class="token punctuation">:</span> dev description 2
</code></pre>
<p>&#x5982;&#x679C; <code>dev</code> &#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x672A;&#x6FC0;&#x6D3B;&#xFF0C;&#x5219; <code>AcmeProperties.map</code> &#x53EA;&#x5305;&#x542B;&#x4E00;&#x4E2A;&#x5E26; <code>key1</code> key &#x7684;&#x6761;&#x76EE;&#xFF08;<code>name</code> &#x4E3A; <code>my name 1</code>&#xFF0C;<code>description</code> &#x4E3A; <code>my description 1</code>&#xFF09;&#x3002;&#x4F46;&#x662F;&#xFF0C;&#x5982;&#x679C;&#x6FC0;&#x6D3B;&#x4E86; dev &#x914D;&#x7F6E;&#x6587;&#x4EF6;&#xFF0C;&#x5219; <code>map</code> &#x5C06;&#x5305;&#x542B;&#x4E24;&#x4E2A;&#x6761;&#x76EE;&#xFF0C; key &#x5206;&#x522B;&#x4E3A; <code>key1</code>&#xFF08;<code>name</code> &#x4E3A; <code>dev name 1</code> &#x548C; <code>description</code> &#x4E3A; <code>my description 1</code>&#xFF09;&#x548C; <code>key2</code>&#xFF08;<code>name</code> &#x4E3A; <code>dev name 2</code> &#x548C; <code>description</code> &#x4E3A; <code>dev description 2</code>&#xFF09;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x524D;&#x9762;&#x7684;&#x5408;&#x5E76;&#x89C4;&#x5219;&#x9002;&#x7528;&#x4E8E;&#x6240;&#x6709;&#x4E0D;&#x540C;&#x5C5E;&#x6027;&#x6E90;&#x7684;&#x5C5E;&#x6027;&#xFF0C;&#x800C;&#x4E0D;&#x4EC5;&#x4EC5;&#x662F; YAML &#x6587;&#x4EF6;&#x3002;</p>
</blockquote>
<p><a id="boot-features-external-config-conversion"></a></p>
<h4 id="2484&#x3001;&#x5C5E;&#x6027;&#x8F6C;&#x6362;">24.8.4&#x3001;&#x5C5E;&#x6027;&#x8F6C;&#x6362;</h4>
<p>&#x5F53;&#x5916;&#x90E8;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5C5E;&#x6027;&#xFF08;application properties&#xFF09; &#x7ED1;&#x5B9A;&#x5230; <code>@ConfigurationProperties</code> bean &#x65F6;&#xFF0C;Spring Boot &#x4F1A;&#x5C1D;&#x8BD5;&#x5C06;&#x5176;&#x5C5E;&#x6027;&#x5F3A;&#x5236;&#x8F6C;&#x6362;&#x4E3A;&#x6B63;&#x786E;&#x7684;&#x7C7B;&#x578B;&#x3002;&#x5982;&#x679C;&#x9700;&#x8981;&#x81EA;&#x5B9A;&#x4E49;&#x7C7B;&#x578B;&#x8F6C;&#x6362;&#xFF0C;&#x53EF;&#x4EE5;&#x63D0;&#x4F9B; <code>ConversionService</code> bean&#xFF08;&#x540D;&#x4E3A; <code>conversionService</code> &#x7684; bean&#xFF09;&#x6216;&#x81EA;&#x5B9A;&#x4E49;&#x5C5E;&#x6027;&#x7F16;&#x8F91;&#x5668;&#xFF08;&#x901A;&#x8FC7; <code>CustomEditorConfigurer</code> bean&#xFF09;&#x6216;&#x81EA;&#x5B9A;&#x4E49;&#x8F6C;&#x6362;&#x5668;&#xFF08;&#x5E26;&#x6709;&#x6CE8;&#x89E3;&#x4E3A; <code>@ConfigurationPropertiesBinding</code> &#x7684; bean &#x5B9A;&#x4E49;&#xFF09;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<p>&#x7531;&#x4E8E;&#x8BE5; bean &#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x751F;&#x547D;&#x5468;&#x671F;&#x65E9;&#x671F;&#x5C31;&#x88AB;&#x8BF7;&#x6C42; &#xFF0C;&#x56E0;&#x6B64;&#x8BF7;&#x9650;&#x5236; <code>ConversionService</code> &#x4F7F;&#x7528;&#x7684;&#x4F9D;&#x8D56;&#x3002;&#x60A8;&#x5728;&#x521B;&#x5EFA;&#x65F6;&#x53EF;&#x80FD;&#x65E0;&#x6CD5;&#x5B8C;&#x5168;&#x521D;&#x59CB;&#x5316;&#x6240;&#x9700;&#x7684;&#x4F9D;&#x8D56;&#x3002;&#x5982;&#x679C;&#x914D;&#x7F6E; key &#x4E3A;&#x975E;&#x5F3A;&#x5236;&#x9700;&#x8981;&#xFF0C;&#x60A8;&#x53EF;&#x80FD;&#x5E0C;&#x671B;&#x91CD;&#x547D;&#x540D;&#x81EA;&#x5B9A;&#x4E49;&#x7684; <code>ConversionService</code>&#xFF0C;&#x5E76;&#x4EC5;&#x4F9D;&#x8D56;&#x4E8E;&#x4F7F;&#x7528; <code>@ConfigurationPropertiesBinding</code> &#x9650;&#x5B9A;&#x7684;&#x81EA;&#x5B9A;&#x4E49;&#x8F6C;&#x6362;&#x5668;&#x3002;</p>
<p><a id="boot-features-external-config-conversion-duration"></a></p>
<h5 id="&#x8F6C;&#x6362;-duration">&#x8F6C;&#x6362; duration</h5>
<p>Spring Boot &#x652F;&#x6301;&#x6301;&#x7EED;&#x65F6;&#x95F4;&#xFF08;duration&#xFF09;&#x8868;&#x8FBE;&#x3002;&#x5982;&#x679C;&#x60A8;&#x66B4;&#x9732;&#x4E00;&#x4E2A; <code>java.time.Duration</code> &#x5C5E;&#x6027;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5C5E;&#x6027;&#x4E2D;&#x4F7F;&#x7528;&#x4EE5;&#x4E0B;&#x683C;&#x5F0F;&#xFF1A;</p>
<ul>
<li>&#x5E38;&#x89C4; <code>long</code> &#x8868;&#x793A;&#xFF08;&#x9664;&#x975E;&#x6307;&#x5B9A; <code>@DurationUnit</code>&#xFF0C;&#x5426;&#x5219;&#x4F7F;&#x7528;&#x6BEB;&#x79D2;&#x4F5C;&#x4E3A;&#x9ED8;&#x8BA4;&#x5355;&#x4F4D;&#xFF09;</li>
<li><a href="https://docs.oracle.com/javase/8/docs/api//java/time/Duration.html#parse-java.lang.CharSequence-" target="_blank"><code>java.util.Duration</code></a> &#x4F7F;&#x7528;&#x7684;&#x6807;&#x51C6; ISO-8601 &#x683C;&#x5F0F;</li>
<li>&#x4E00;&#x79CD;&#x66F4;&#x6613;&#x8BFB;&#x7684;&#x683C;&#x5F0F;&#xFF0C;&#x503C;&#x548C;&#x5355;&#x4F4D;&#x5728;&#x4E00;&#x8D77;&#xFF08;&#x4F8B;&#x5982; <code>10s</code> &#x8868;&#x793A; 10 &#x79D2;&#xFF09;</li>
</ul>
<p>&#x601D;&#x8003;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span><span class="token string">&quot;app.system&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AppSystemProperties</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@DurationUnit</span><span class="token punctuation">(</span><span class="token class-name">ChronoUnit</span><span class="token punctuation">.</span>SECONDS<span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">Duration</span> sessionTimeout <span class="token operator">=</span> <span class="token class-name">Duration</span><span class="token punctuation">.</span><span class="token function">ofSeconds</span><span class="token punctuation">(</span><span class="token number">30</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">private</span> <span class="token class-name">Duration</span> readTimeout <span class="token operator">=</span> <span class="token class-name">Duration</span><span class="token punctuation">.</span><span class="token function">ofMillis</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">Duration</span> <span class="token function">getSessionTimeout</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>sessionTimeout<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setSessionTimeout</span><span class="token punctuation">(</span><span class="token class-name">Duration</span> sessionTimeout<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>sessionTimeout <span class="token operator">=</span> sessionTimeout<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">Duration</span> <span class="token function">getReadTimeout</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>readTimeout<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setReadTimeout</span><span class="token punctuation">(</span><span class="token class-name">Duration</span> readTimeout<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>readTimeout <span class="token operator">=</span> readTimeout<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x6307;&#x5B9A;&#x4E00;&#x4E2A;&#x4F1A;&#x8BDD;&#x8D85;&#x65F6;&#x65F6;&#x95F4;&#x4E3A; 30 &#x79D2;&#xFF0C;&#x4F7F;&#x7528; <code>30</code>&#x3001;<code>PT30S</code> &#x548C; <code>30s</code> &#x7B49;&#x5F62;&#x5F0F;&#x90FD;&#x662F;&#x53EF;&#x4EE5;&#x7684;&#x3002;&#x8BFB;&#x53D6;&#x8D85;&#x65F6;&#x65F6;&#x95F4;&#x8BBE;&#x7F6E;&#x4E3A; 500ms&#xFF0C;&#x53EF;&#x4EE5;&#x91C7;&#x7528;&#x4EE5;&#x4E0B;&#x4EFB;&#x4F55;&#x4E00;&#x79CD;&#x5F62;&#x5F0F;&#xFF1A;<code>500</code>&#x3001;<code>PT0.5S</code> &#x548C; <code>500ms</code>&#x3002;</p>
<p>&#x60A8;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4EFB;&#x4F55;&#x652F;&#x6301;&#x7684;&#x5355;&#x4F4D;&#x6765;&#x6807;&#x8BC6;&#xFF1A;</p>
<ul>
<li><code>ns</code> &#x4E3A;&#x7EB3;&#x79D2;</li>
<li><code>us</code> &#x4E3A;&#x5FAE;&#x79D2;</li>
<li><code>ms</code> &#x4E3A;&#x6BEB;&#x79D2;</li>
<li><code>s</code> &#x4E3A;&#x79D2;</li>
<li><code>m</code> &#x4E3A;&#x5206;&#x949F;</li>
<li><code>h</code> &#x4E3A;&#x5C0F;&#x65F6;</li>
<li><code>d</code> &#x4E3A;&#x5929;</li>
</ul>
<p>&#x9ED8;&#x8BA4;&#x5355;&#x4F4D;&#x662F;&#x6BEB;&#x79D2;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@DurationUnit</code> &#x914D;&#x5408;&#x4E0A;&#x9762;&#x7684;&#x5355;&#x4F4D;&#x793A;&#x4F8B;&#x91CD;&#x5199;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x8981;&#x4ECE;&#x5148;&#x524D;&#x4EC5;&#x4F7F;&#x7528; <code>Long</code> &#x6765;&#x8868;&#x793A;&#x6301;&#x7EED;&#x65F6;&#x95F4;&#x7684;&#x7248;&#x672C;&#x8FDB;&#x884C;&#x5347;&#x7EA7;&#xFF0C;&#x5982;&#x679C;&#x5207;&#x6362;&#x5230; <code>Duration</code> &#x65F6;&#x4E0D;&#x662F;&#x6BEB;&#x79D2;&#xFF0C;&#x8BF7;&#x5B9A;&#x4E49;&#x5355;&#x4F4D;&#xFF08;&#x4F7F;&#x7528; <code>@DurationUnit</code>&#xFF09;&#x3002;&#x8FD9;&#x6837;&#x505A;&#x53EF;&#x4EE5;&#x63D0;&#x4F9B;&#x900F;&#x660E;&#x7684;&#x5347;&#x7EA7;&#x8DEF;&#x5F84;&#xFF0C;&#x540C;&#x65F6;&#x652F;&#x6301;&#x66F4;&#x4E30;&#x5BCC;&#x7684;&#x683C;&#x5F0F;&#x3002;</p>
</blockquote>
<p><a id="boot-features-external-config-conversion-datasize"></a></p>
<h5 id="&#x8F6C;&#x6362;-data-size">&#x8F6C;&#x6362; Data Size</h5>
<p>Spring Framework &#x6709;&#x4E00;&#x4E2A; <code>DataSize</code> &#x503C;&#x7C7B;&#x578B;&#xFF0C;&#x5141;&#x8BB8;&#x4EE5;&#x5B57;&#x8282;&#x8868;&#x793A;&#x5927;&#x5C0F;&#x3002;&#x5982;&#x679C;&#x66B4;&#x9732;&#x4E00;&#x4E2A; <code>DataSize</code> &#x5C5E;&#x6027;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5C5E;&#x6027;&#x4E2D;&#x4F7F;&#x7528;&#x4EE5;&#x4E0B;&#x683C;&#x5F0F;&#xFF1A;</p>
<ul>
<li>&#x5E38;&#x89C4;&#x7684; <code>Long</code> &#x8868;&#x793A;&#xFF08;&#x4F7F;&#x7528;&#x5B57;&#x8282;&#x4F5C;&#x4E3A;&#x9ED8;&#x8BA4;&#x5355;&#x4F4D;&#xFF0C;&#x9664;&#x975E;&#x6307;&#x5B9A;&#x4E86; <code>@DataSizeUnit</code>&#xFF09;</li>
<li>&#x66F4;&#x5177;&#x6709;&#x53EF;&#x8BFB;&#x6027;&#x7684;&#x683C;&#x5F0F;&#xFF0C;&#x503C;&#x548C;&#x5355;&#x4F4D;&#x5728;&#x4E00;&#x8D77;&#xFF08;&#x4F8B;&#x5982; <code>10MB</code> &#x8868;&#x793A; <code>10</code> &#x5146;&#x5B57;&#x8282;&#xFF09;</li>
</ul>
<p>&#x8BF7;&#x601D;&#x8003;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span><span class="token string">&quot;app.io&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AppIoProperties</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@DataSizeUnit</span><span class="token punctuation">(</span><span class="token class-name">DataUnit</span><span class="token punctuation">.</span>MEGABYTES<span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">DataSize</span> bufferSize <span class="token operator">=</span> <span class="token class-name">DataSize</span><span class="token punctuation">.</span><span class="token function">ofMegabytes</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">private</span> <span class="token class-name">DataSize</span> sizeThreshold <span class="token operator">=</span> <span class="token class-name">DataSize</span><span class="token punctuation">.</span><span class="token function">ofBytes</span><span class="token punctuation">(</span><span class="token number">512</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">DataSize</span> <span class="token function">getBufferSize</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>bufferSize<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setBufferSize</span><span class="token punctuation">(</span><span class="token class-name">DataSize</span> bufferSize<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>bufferSize <span class="token operator">=</span> bufferSize<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">DataSize</span> <span class="token function">getSizeThreshold</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>sizeThreshold<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setSizeThreshold</span><span class="token punctuation">(</span><span class="token class-name">DataSize</span> sizeThreshold<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>sizeThreshold <span class="token operator">=</span> sizeThreshold<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x8981;&#x6307;&#x5B9A; 10 &#x5146;&#x5B57;&#x8282;&#x7684;&#x7F13;&#x51B2;&#x5927;&#x5C0F;&#xFF0C;&#x4F7F;&#x7528; <code>10</code> &#x548C; <code>10MB</code> &#x662F;&#x7B49;&#x6548;&#x7684;&#x3002;256 &#x5B57;&#x8282;&#x7684;&#x5927;&#x5C0F;&#x53EF;&#x4EE5;&#x6307;&#x5B9A;&#x4E3A; <code>256</code> &#x6216; <code>256B</code>&#x3002;</p>
<p>&#x60A8;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4EFB;&#x4F55;&#x652F;&#x6301;&#x7684;&#x5355;&#x4F4D;&#xFF1A;</p>
<ul>
<li><code>B</code> &#x8868;&#x793A;&#x5B57;&#x8282;</li>
<li><code>KB</code> &#x4E3A;&#x5343;&#x5B57;&#x8282;</li>
<li><code>MB</code> &#x4E3A;&#x5146;&#x5B57;&#x8282;</li>
<li><code>GB</code> &#x4E3A;&#x5343;&#x5146;&#x5B57;&#x8282;</li>
<li><code>TB</code> &#x4E3A;&#x5146;&#x5146;&#x5B57;&#x8282;</li>
</ul>
<p>&#x9ED8;&#x8BA4;&#x5355;&#x4F4D;&#x662F;&#x5B57;&#x8282;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@DataSizeUnit</code> &#x914D;&#x5408;&#x4E0A;&#x9762;&#x7684;&#x793A;&#x4F8B;&#x5355;&#x4F4D;&#x91CD;&#x5199;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x8981;&#x4ECE;&#x5148;&#x524D;&#x4EC5;&#x4F7F;&#x7528; <code>Long</code> &#x6765;&#x8868;&#x793A;&#x5927;&#x5C0F;&#x7684;&#x7248;&#x672C;&#x8FDB;&#x884C;&#x5347;&#x7EA7;&#xFF0C;&#x8BF7;&#x786E;&#x4FDD;&#x5728;&#x5207;&#x6362;&#x5230; <code>DataSize</code> &#x4E0D;&#x662F;&#x5B57;&#x8282;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#x5B9A;&#x4E49;&#x5355;&#x4F4D;&#xFF08;&#x4F7F;&#x7528; <code>@DataSizeUnit</code>&#xFF09;&#x3002;&#x8FD9;&#x6837;&#x505A;&#x53EF;&#x4EE5;&#x63D0;&#x4F9B;&#x900F;&#x660E;&#x7684;&#x5347;&#x7EA7;&#x8DEF;&#x5F84;&#xFF0C;&#x540C;&#x65F6;&#x652F;&#x6301;&#x66F4;&#x4E30;&#x5BCC;&#x7684;&#x683C;&#x5F0F;&#x3002;</p>
</blockquote>
<p><a id="boot-features-external-config-validation"></a></p>
<h4 id="2485&#x3001;configurationproperties-&#x9A8C;&#x8BC1;">24.8.5&#x3001;@ConfigurationProperties &#x9A8C;&#x8BC1;</h4>
<p>&#x53EA;&#x8981;&#x4F7F;&#x7528;&#x4E86; Spring &#x7684; <code>@Validated</code> &#x6CE8;&#x89E3;&#xFF0C;Spring Boot &#x5C31;&#x4F1A;&#x5C1D;&#x8BD5;&#x9A8C;&#x8BC1; <code>@ConfigurationProperties</code> &#x7C7B;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x5728;&#x914D;&#x7F6E;&#x7C7B;&#x4E0A;&#x4F7F;&#x7528; JSR-303 <code>javax.validation</code> &#x7EA6;&#x675F;&#x6CE8;&#x89E3;&#x3002;&#x4E3A;&#x6B64;&#xFF0C;&#x8BF7;&#x786E;&#x4FDD; JSR-303 &#x5B9E;&#x73B0;&#x5728; classpath &#x4E0A;&#xFF0C;&#x7136;&#x540E;&#x5C06;&#x7EA6;&#x675F;&#x6CE8;&#x89E3;&#x6DFB;&#x52A0;&#x5230;&#x5B57;&#x6BB5;&#x4E0A;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix<span class="token operator">=</span><span class="token string">&quot;acme&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@Validated</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AcmeProperties</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@NotNull</span>
    <span class="token keyword">private</span> <span class="token class-name">InetAddress</span> remoteAddress<span class="token punctuation">;</span>

    <span class="token comment">// ... getters and setters</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4F7F;&#x7528; <code>@Validated</code> &#x6CE8;&#x89E3;&#x521B;&#x5EFA;&#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x7684; <code>@Bean</code> &#x65B9;&#x6CD5;&#x6765;&#x89E6;&#x53D1;&#x9A8C;&#x8BC1;&#x3002;</p>
</blockquote>
<p>&#x867D;&#x7136;&#x7ED1;&#x5B9A;&#x65F6;&#x4E5F;&#x4F1A;&#x9A8C;&#x8BC1;&#x5D4C;&#x5957;&#x5C5E;&#x6027;&#xFF0C;&#x4F46;&#x6700;&#x597D;&#x7684;&#x505A;&#x6CD5;&#x8FD8;&#x662F;&#x5C06;&#x5173;&#x8054;&#x5B57;&#x6BB5;&#x6CE8;&#x89E3;&#x4E0A; <code>@Valid</code>&#x3002;&#x8FD9;&#x53EF;&#x786E;&#x4FDD;&#x5373;&#x4F7F;&#x672A;&#x627E;&#x5230;&#x5D4C;&#x5957;&#x5C5E;&#x6027;&#x4E5F;&#x4F1A;&#x89E6;&#x53D1;&#x9A8C;&#x8BC1;&#x3002;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x57FA;&#x4E8E;&#x524D;&#x9762;&#x7684; <code>AcmeProperties</code> &#x793A;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@ConfigurationProperties</span><span class="token punctuation">(</span>prefix<span class="token operator">=</span><span class="token string">&quot;acme&quot;</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@Validated</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AcmeProperties</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@NotNull</span>
    <span class="token keyword">private</span> <span class="token class-name">InetAddress</span> remoteAddress<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Valid</span>
    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">Security</span> security <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Security</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment">// ... getters and setters</span>

    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">Security</span> <span class="token punctuation">{</span>

        <span class="token annotation punctuation">@NotEmpty</span>
        <span class="token keyword">public</span> <span class="token class-name">String</span> username<span class="token punctuation">;</span>

        <span class="token comment">// ... getters and setters</span>

    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x540D;&#x4E3A; <code>configurationPropertiesValidator</code> &#x7684; bean &#x5B9A;&#x4E49;&#x6765;&#x6DFB;&#x52A0;&#x81EA;&#x5B9A;&#x4E49; Spring <code>Validator</code>&#x3002;&#x5E94;&#x8BE5;&#x5C06; <code>@Bean</code> &#x65B9;&#x6CD5;&#x58F0;&#x660E;&#x4E3A; <code>static</code>&#x3002;&#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x9A8C;&#x8BC1;&#x5668;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x751F;&#x547D;&#x5468;&#x671F;&#x7684;&#x65E9;&#x671F;&#x521B;&#x5EFA;&#xFF0C;&#x5C06; <code>@Bean</code> &#x65B9;&#x6CD5;&#x58F0;&#x660E;&#x4E3A; <code>static</code> &#x53EF;&#x4EE5;&#x65E0;&#x9700;&#x5B9E;&#x4F8B;&#x5316; <code>@Configuration</code> &#x7C7B;&#x6765;&#x521B;&#x5EFA; bean&#x3002;&#x8FD9;&#x6837;&#x505A;&#x53EF;&#x4EE5;&#x907F;&#x514D;&#x65E9;&#x671F;&#x5B9E;&#x4F8B;&#x5316;&#x53EF;&#x80FD;&#x5BFC;&#x81F4;&#x7684;&#x610F;&#x5916;&#x95EE;&#x9898;&#x3002;&#x8FD9;&#x91CC;&#x6709;&#x4E00;&#x4E2A;<a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-samples/spring-boot-sample-property-validation" target="_blank">&#x5C5E;&#x6027;&#x9A8C;&#x8BC1;&#x793A;&#x4F8B;</a>&#xFF0C;&#x8BB2;&#x89E3;&#x4E86;&#x5982;&#x4F55;&#x8BBE;&#x7F6E;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p><code>spring-boot-actuator</code> &#x6A21;&#x5757;&#x5305;&#x62EC;&#x4E00;&#x4E2A;&#x66B4;&#x9732;&#x6240;&#x6709; <code>@ConfigurationProperties</code> bean &#x7684;&#x7AEF;&#x70B9;&#x3002;&#x53EF;&#x5C06; Web &#x6D4F;&#x89C8;&#x5668;&#x6307;&#x5411; <code>/actuator/configprops</code> &#x6216;&#x4F7F;&#x7528;&#x7B49;&#x6548;&#x7684; JMX &#x7AEF;&#x70B9;&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605;<a href="#production-ready-endpoints">&#x751F;&#x4EA7;&#x5C31;&#x7EEA;&#x529F;&#x80FD;</a>&#x90E8;&#x5206;&#x3002;</p>
</blockquote>
<p><a id="boot-features-external-config-vs-value"></a></p>
<h4 id="2486&#x3001;configurationproperties-&#x4E0E;-value-&#x5BF9;&#x6BD4;">24.8.6&#x3001;@ConfigurationProperties &#x4E0E; @Value &#x5BF9;&#x6BD4;</h4>
<p><code>@Value</code> &#x6CE8;&#x89E3;&#x662F;&#x6838;&#x5FC3;&#x5BB9;&#x5668;&#x529F;&#x80FD;&#xFF0C;&#x5B83;&#x4E0D;&#x63D0;&#x4F9B;&#x4E0E;&#x7C7B;&#x578B;&#x5B89;&#x5168;&#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x76F8;&#x540C;&#x7684;&#x529F;&#x80FD;&#x3002;&#x4E0B;&#x8868;&#x603B;&#x7ED3;&#x4E86; <code>@ConfigurationProperties</code> &#x548C; <code>@Value</code> &#x652F;&#x6301;&#x7684;&#x529F;&#x80FD;&#xFF1A;</p>
<table>
<thead>
<tr>
<th>&#x529F;&#x80FD;</th>
<th><code>@ConfigurationProperties</code></th>
<th><code>@Value</code></th>
</tr>
</thead>
<tbody>
<tr>
<td><a href="#boot-features-external-config-relaxed-binding">&#x5BBD;&#x677E;&#x7ED1;&#x5B9A;</a></td>
<td>&#x662F;</td>
<td>&#x5426;</td>
</tr>
<tr>
<td><a href="#configuration-metadata">&#x5143;&#x6570;&#x636E;&#x652F;&#x6301;</a></td>
<td>&#x662F;</td>
<td>&#x5426;</td>
</tr>
<tr>
<td><code>SpEL</code> &#x8868;&#x8FBE;&#x5F0F;</td>
<td>&#x5426;</td>
<td>&#x662F;</td>
</tr>
</tbody>
</table>
<p>&#x5982;&#x679C;&#x60A8;&#x8981;&#x4E3A;&#x81EA;&#x5DF1;&#x7684;&#x7EC4;&#x4EF6;&#x5B9A;&#x4E49;&#x4E00;&#x7EC4;&#x914D;&#x7F6E; key&#xFF0C;&#x6211;&#x4EEC;&#x5EFA;&#x8BAE;&#x60A8;&#x5C06;&#x5B83;&#x4EEC;&#x5206;&#x7EC4;&#x5230;&#x4F7F;&#x7528; <code>@ConfigurationProperties</code> &#x6CE8;&#x89E3;&#x7684; POJO &#x4E2D;&#x3002;&#x60A8;&#x5E94;&#x8BE5;&#x77E5;&#x9053;&#xFF0C;&#x7531;&#x4E8E; <code>@Value</code> &#x4E0D;&#x652F;&#x6301;&#x5BBD;&#x677E;&#x7ED1;&#x5B9A;&#xFF0C;&#x56E0;&#x6B64;&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x901A;&#x8FC7;&#x73AF;&#x5883;&#x53D8;&#x91CF;&#x6765;&#x63D0;&#x4F9B;&#x503C;&#xFF0C;&#x5B83;&#x5E76;&#x4E0D;&#x662F;&#x4E00;&#x4E2A;&#x597D;&#x7684;&#x9009;&#x62E9;&#x3002;</p>
<p>&#x6700;&#x540E;&#xFF0C;&#x867D;&#x7136;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>@Value</code> &#x4E2D;&#x7F16;&#x5199; <code>SpEL</code> &#x8868;&#x8FBE;&#x5F0F;&#xFF0C;&#x4F46;&#x6765;&#x81EA;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5C5E;&#x6027;&#x6587;&#x4EF6;&#x7684;&#x6B64;&#x7C7B;&#x8868;&#x8FBE;&#x5F0F;&#x5E76;&#x4E0D;&#x4F1A;&#x88AB;&#x5904;&#x7406;&#x3002;</p>
<p><a id="boot-features-profiles"></a></p>
<h2 id="25&#x3001;profile">25&#x3001;Profile</h2>
<p>Spring Profile &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x79CD;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x914D;&#x7F6E;&#x90E8;&#x5206;&#x9694;&#x79BB;&#x5E76;&#x4F7F;&#x5176;&#x4EC5;&#x5728;&#x7279;&#x5B9A;&#x73AF;&#x5883;&#x4E2D;&#x53EF;&#x7528;&#x7684;&#x65B9;&#x6CD5;&#x3002;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@Profile</code> &#x6765;&#x6CE8;&#x89E3;&#x4EFB;&#x4F55; <code>@Component</code> &#x6216; <code>@Configuration</code> &#x4EE5;&#x6307;&#x5B9A;&#x4F55;&#x65F6;&#x52A0;&#x8F7D;&#x5B83;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@Profile</span><span class="token punctuation">(</span><span class="token string">&quot;production&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ProductionConfiguration</span> <span class="token punctuation">{</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.profiles.active</code> <code>Environment</code> &#x5C5E;&#x6027;&#x6307;&#x5B9A;&#x54EA;&#x4E9B;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x5904;&#x4E8E;&#x6FC0;&#x6D3B;&#x72B6;&#x6001;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x672C;&#x7AE0;&#x524D;&#x9762;&#x4ECB;&#x7ECD;&#x7684;&#x4EFB;&#x4F55;&#x65B9;&#x6CD5;&#x6307;&#x5B9A;&#x5C5E;&#x6027;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5C06;&#x5176;&#x5305;&#x542B;&#x5728; <code>application.properties</code> &#x4E2D;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.profiles.active</span><span class="token attr-value"><span class="token punctuation">=</span>dev,hsqldb</span>
</code></pre>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x5728;&#x547D;&#x4EE4;&#x884C;&#x4E0A;&#x4F7F;&#x7528;&#x4EE5;&#x4E0B;&#x5F00;&#x5173;&#x6307;&#x5B9A;&#x5B83;&#xFF1A;<code>--spring.profiles.active=dev,hsqldb</code>&#x3002;</p>
<p><a id="boot-features-adding-active-profiles"></a></p>
<h3 id="251&#x3001;&#x6DFB;&#x52A0;&#x6FC0;&#x6D3B;-profile">25.1&#x3001;&#x6DFB;&#x52A0;&#x6FC0;&#x6D3B; Profile</h3>
<p><code>spring.profiles.active</code> &#x5C5E;&#x6027;&#x9075;&#x5FAA;&#x4E0E;&#x5176;&#x4ED6;&#x5C5E;&#x6027;&#x76F8;&#x540C;&#x7684;&#x6392;&#x5E8F;&#x89C4;&#x5219;&#xFF1A;&#x5E94;&#x7528;&#x4F18;&#x5148;&#x7EA7;&#x6700;&#x9AD8;&#x7684; <code>PropertySource</code>&#x3002;&#x8FD9;&#x610F;&#x5473;&#x7740;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>application.properties</code> &#x4E2D;&#x6307;&#x5B9A;&#x6FC0;&#x6D3B;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#xFF0C;&#x7136;&#x540E;&#x4F7F;&#x7528;&#x547D;&#x4EE4;&#x884C;&#x5F00;&#x5173;<strong>&#x66FF;&#x6362;</strong>&#x5B83;&#x4EEC;&#x3002;</p>
<p>&#x6709;&#x65F6;&#xFF0C;&#x5C06;&#x7279;&#x5B9A; profile &#x7684;&#x5C5E;&#x6027;<strong>&#x6DFB;&#x52A0;</strong>&#x5230;&#x6FC0;&#x6D3B;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x800C;&#x4E0D;&#x662F;&#x66FF;&#x6362;&#x5B83;&#x4EEC;&#xFF0C;&#x8FD9;&#x79CD;&#x65B9;&#x5F0F;&#x4E5F;&#x662F;&#x5F88;&#x6709;&#x7528;&#x7684;&#x3002;<code>spring.profiles.include</code> &#x5C5E;&#x6027;&#x53EF;&#x65E0;&#x6761;&#x4EF6;&#x5730;&#x6DFB;&#x52A0;&#x6FC0;&#x6D3B;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x3002;<code>SpringApplication</code> &#x5165;&#x53E3;&#x8FD8;&#x6709;&#x4E00;&#x4E2A; Java API&#xFF0C;&#x7528;&#x4E8E;&#x8BBE;&#x7F6E;&#x5176;&#x4ED6; profile&#xFF08;&#x5373;&#xFF0C;&#x5728; <code>spring.profiles.active</code> &#x5C5E;&#x6027;&#x6FC0;&#x6D3B;&#x7684; profile &#x4E4B;&#x4E0A;&#xFF09;&#x3002;&#x8BF7;&#x53C2;&#x9605;SpringApplication &#x4E2D;&#x7684; <code>setAdditionalProfiles()</code> &#x65B9;&#x6CD5;&#x3002;</p>
<p>&#x4F8B;&#x5982;&#xFF0C;&#x5F53;&#x4F7F;&#x7528;&#x5F00;&#x5173; <code>--spring.profiles.active=prod</code> &#x8FD0;&#x884C;&#x6709;&#x4EE5;&#x4E0B;&#x5C5E;&#x6027;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x65F6;&#xFF0C;<code>proddb</code> &#x548C; <code>prodmq</code> &#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4E5F;&#x4F1A;&#x88AB;&#x6FC0;&#x6D3B;&#xFF1A;</p>
<pre class="language-"><code class="lang-yaml"><span class="token punctuation">---</span>
<span class="token key atrule">my.property</span><span class="token punctuation">:</span> fromyamlfile
<span class="token punctuation">---</span>
<span class="token key atrule">spring.profiles</span><span class="token punctuation">:</span> prod
<span class="token key atrule">spring.profiles.include</span><span class="token punctuation">:</span>
  <span class="token punctuation">-</span> proddb
  <span class="token punctuation">-</span> prodmq
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x8BF7;&#x8BB0;&#x4F4F;&#xFF0C;&#x53EF;&#x4EE5;&#x5728; YAML &#x6587;&#x6863;&#x4E2D;&#x5B9A;&#x4E49; <code>spring.profiles</code> &#x5C5E;&#x6027;&#xFF0C;&#x4EE5;&#x786E;&#x5B9A;&#x6B64;&#x7279;&#x5B9A;&#x6587;&#x6863;&#x4F55;&#x65F6;&#x5305;&#x542B;&#x5728;&#x914D;&#x7F6E;&#x4E2D;&#x3002;&#x6709;&#x5173;&#x66F4;&#x591A;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x89C1;&#x7B2C; 77.7 &#x7AE0;&#x8282;&#xFF1A;<a href="howto.md#howto-change-configuration-depending-on-the-environment">&#x6839;&#x636E;&#x73AF;&#x5883;&#x66F4;&#x6539;&#x914D;&#x7F6E;</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-programmatically-setting-profiles"></a></p>
<h3 id="252&#x3001;&#x4EE5;&#x7F16;&#x7A0B;&#x65B9;&#x5F0F;&#x8BBE;&#x7F6E;-profile">25.2&#x3001;&#x4EE5;&#x7F16;&#x7A0B;&#x65B9;&#x5F0F;&#x8BBE;&#x7F6E; Profile</h3>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x8FD0;&#x884C;&#x4E4B;&#x524D;&#x4EE5;&#x7F16;&#x7A0B;&#x65B9;&#x5F0F;&#x901A;&#x8FC7;&#x8C03;&#x7528; <code>SpringApplication.setAdditionalProfiles(...)</code> &#x8BBE;&#x7F6E;&#x6FC0;&#x6D3B; profile&#x3002;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; Spring &#x7684; <code>ConfigurableEnvironment</code> &#x63A5;&#x53E3;&#x6FC0;&#x6D3B; profile&#x3002;</p>
<p><a id="boot-features-profile-specific-configuration"></a></p>
<h3 id="253&#x3001;&#x7279;&#x5B9A;-profile-&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;">25.3&#x3001;&#x7279;&#x5B9A; Profile &#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;</h3>
<p>&#x7279;&#x5B9A; profile &#x7684; <code>application.properties</code>&#xFF08;&#x6216; <code>application.yml</code>&#xFF09;&#x548C;&#x901A;&#x8FC7; <code>@ConfigurationProperties</code> &#x5F15;&#x7528;&#x7684;&#x6587;&#x4EF6;&#x88AB;&#x5F53;&#x505A;&#x6587;&#x4EF6;&#x5E76;&#x52A0;&#x8F7D;&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x89C1;<a href="#boot-features-external-config-profile-specific-properties">&#x7B2C; 24.4 &#x7AE0;&#x8282;&#xFF1A;&#x7279;&#x5B9A; Profile &#x7684;&#x5C5E;&#x6027;&#x6587;&#x4EF6;</a>&#x3002;</p>
<p><a id="boot-features-logging"></a></p>
<h2 id="26&#x3001;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;">26&#x3001;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;</h2>
<p>Spring Boot &#x4F7F;&#x7528; <a href="https://commons.apache.org/logging" target="_blank">Commons Logging</a> &#x8BB0;&#x5F55;&#x6240;&#x6709;&#x5185;&#x90E8;&#x65E5;&#x5FD7;&#xFF0C;&#x4F46;&#x5F00;&#x653E;&#x65E5;&#x5FD7;&#x7684;&#x5E95;&#x5C42;&#x5B9E;&#x73B0;&#x3002;&#x5176;&#x4E3A; <a href="https://docs.oracle.com/javase/8/docs/api//java/util/logging/package-summary.html" target="_blank">Java Util Logging
</a>&#x3001;<a href="https://logging.apache.org/log4j/2.x/" target="_blank">Log4J2</a> &#x548C; <a href="http://logback.qos.ch/" target="_blank">Logback</a> &#x63D0;&#x4F9B;&#x4E86;&#x9ED8;&#x8BA4;&#x914D;&#x7F6E;&#x3002;&#x5728;&#x6BCF;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5668;&#x90FD;&#x9884;&#x5148;&#x914D;&#x7F6E;&#x4E3A;&#x4F7F;&#x7528;&#x63A7;&#x5236;&#x53F0;&#x8F93;&#x51FA;&#xFF0C;&#x5E76;&#x4E14;&#x8FD8;&#x63D0;&#x4F9B;&#x53EF;&#x9009;&#x7684;&#x6587;&#x4EF6;&#x8F93;&#x51FA;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528;&#x4E86; <strong>Starter</strong>&#xFF0C;&#x5219;&#x4F7F;&#x7528; Logback &#x8FDB;&#x884C;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x3002;&#x8FD8;&#x5305;&#x62EC;&#x5408;&#x9002;&#x7684; Logback &#x8DEF;&#x7531;&#xFF0C;&#x4EE5;&#x786E;&#x4FDD;&#x5728;&#x4F7F;&#x7528; Java Util Logging&#x3001;Commons Logging&#x3001;Log4J &#x6216; SLF4J &#x7684;&#x4F9D;&#x8D56;&#x5E93;&#x90FD;&#x80FD;&#x6B63;&#x5E38;&#x5DE5;&#x4F5C;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>Java &#x6709;&#x5F88;&#x591A;&#x65E5;&#x5FD7;&#x6846;&#x67B6;&#x53EF;&#x4F9B;&#x4F7F;&#x7528;&#x3002;&#x5982;&#x679C;&#x4EE5;&#x4E0A;&#x5217;&#x8868;&#x8BA9;&#x60A8;&#x611F;&#x5230;&#x56F0;&#x60D1;&#xFF0C;&#x8BF7;&#x4E0D;&#x8981;&#x62C5;&#x5FC3;&#x3002;&#x901A;&#x5E38;&#xFF0C;&#x60A8;&#x4E0D;&#x9700;&#x8981;&#x66F4;&#x6539;&#x65E5;&#x5FD7;&#x4F9D;&#x8D56;&#xFF0C;&#x5E76;&#x4E14; Spring Boot &#x63D0;&#x4F9B;&#x7684;&#x9ED8;&#x8BA4;&#x914D;&#x7F6E;&#x53EF;&#x4EE5;&#x4FDD;&#x8BC1;&#x65E5;&#x5FD7;&#x6B63;&#x5E38;&#x5DE5;&#x4F5C;&#x3002;</p>
</blockquote>
<p><a id="boot-features-logging-format"></a></p>
<h3 id="261&#x3001;&#x65E5;&#x5FD7;&#x683C;&#x5F0F;">26.1&#x3001;&#x65E5;&#x5FD7;&#x683C;&#x5F0F;</h3>
<p>Spring Boot &#x9ED8;&#x8BA4;&#x65E5;&#x5FD7;&#x8F93;&#x51FA;&#x7C7B;&#x4F3C;&#x4E8E;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code>2014-03-05 10:57:51.112  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52
2014-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2014-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1358 ms
2014-03-05 10:57:51.698  INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: &apos;dispatcherServlet&apos; to [/]
2014-03-05 10:57:51.702  INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: &apos;hiddenHttpMethodFilter&apos; to: [/*]
</code></pre><p>&#x8F93;&#x51FA;&#x4EE5;&#x4E0B;&#x9879;&#xFF1A;</p>
<ul>
<li>&#x65E5;&#x671F;&#x548C;&#x65F6;&#x95F4;&#xFF1A;&#x6BEB;&#x79D2;&#x7CBE;&#x5EA6;&#xFF0C;&#x6613;&#x4E8E;&#x6392;&#x5E8F;&#x3002;</li>
<li>&#x65E5;&#x5FD7;&#x7EA7;&#x522B;&#xFF1A;<code>ERROR</code>&#x3001;<code>WARN</code>&#x3001;<code>INFO</code>&#x3001;<code>DEBUG</code> &#x6216; <code>TRACE</code>&#x3002;</li>
<li>&#x8FDB;&#x7A0B; ID&#x3002;</li>
<li>&#x4E00;&#x4E2A; <code>---</code> &#x5206;&#x9694;&#x7B26;&#xFF0C;&#x7528;&#x4E8E;&#x533A;&#x5206;&#x5B9E;&#x9645;&#x65E5;&#x5FD7;&#x5185;&#x5BB9;&#x7684;&#x5F00;&#x59CB;&#x3002;</li>
<li>&#x7EBF;&#x7A0B;&#x540D;&#x79F0;&#xFF1A;&#x5728;&#x65B9;&#x62EC;&#x53F7;&#x4E2D;&#xFF08;&#x53EF;&#x80FD;&#x4F1A;&#x622A;&#x65AD;&#x63A7;&#x5236;&#x53F0;&#x8F93;&#x51FA;&#xFF09;&#x3002;</li>
<li>&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5668;&#x540D;&#x79F0;&#xFF1A;&#x8FD9;&#x901A;&#x5E38;&#x662F;&#x6E90;&#x7C7B;&#x540D;&#x79F0;&#xFF08;&#x901A;&#x5E38;&#x4E3A;&#x7F29;&#x5199;&#xFF09;&#x3002;</li>
<li>&#x65E5;&#x5FD7;&#x5185;&#x5BB9;&#x3002;</li>
</ul>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>Logback &#x6CA1;&#x6709; <code>FATAL</code> &#x7EA7;&#x522B;&#x3002;&#x8BE5;&#x7EA7;&#x522B;&#x6620;&#x5C04;&#x5230; <code>ERROR</code>&#x3002;</p>
</blockquote>
<p><a id="boot-features-logging-console-output"></a></p>
<h3 id="262&#x3001;&#x63A7;&#x5236;&#x53F0;&#x8F93;&#x51FA;">26.2&#x3001;&#x63A7;&#x5236;&#x53F0;&#x8F93;&#x51FA;</h3>
<p>&#x9ED8;&#x8BA4;&#x65E5;&#x5FD7;&#x914D;&#x7F6E;&#x4F1A;&#x5728;&#x5199;&#x5165;&#x65F6;&#x5C06;&#x6D88;&#x606F;&#x56DE;&#x663E;&#x5230;&#x63A7;&#x5236;&#x53F0;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x4F1A;&#x8BB0;&#x5F55; <code>ERROR</code>&#x3001;<code>WARN</code> &#x548C; <code>INFO</code> &#x7EA7;&#x522B;&#x7684;&#x65E5;&#x5FD7;&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4F7F;&#x7528; <code>--debug</code> &#x6807;&#x5FD7;&#x542F;&#x52A8;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x6765;&#x542F;&#x7528;<strong>&#x8C03;&#x8BD5;</strong>&#x6A21;&#x5F0F;&#x3002;</p>
<pre class="language-"><code class="lang-bash">$ java -jar myapp.jar --debug
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x5728; <code>application.properties</code> &#x4E2D;&#x6307;&#x5B9A; <code>debug=true</code>&#x3002;</p>
</blockquote>
<p>&#x542F;&#x7528;&#x8C03;&#x8BD5;&#x6A21;&#x5F0F;&#x540E;&#xFF0C;&#x6838;&#x5FC3;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5668;&#xFF08;&#x5185;&#x5D4C;&#x5BB9;&#x5668;&#x3001;Hibernate &#x548C; Spring Boot&#xFF09;&#x5C06;&#x88AB;&#x914D;&#x7F6E;&#x4E3A;&#x8F93;&#x51FA;&#x66F4;&#x591A;&#x65E5;&#x5FD7;&#x4FE1;&#x606F;&#x3002;&#x542F;&#x7528;&#x8C03;&#x8BD5;&#x6A21;&#x5F0F;&#x4E0D;&#x4F1A;&#x5C06;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x914D;&#x7F6E;&#x4E3A;&#x4F7F;&#x7528; <code>DEBUG</code> &#x7EA7;&#x522B;&#x8BB0;&#x5F55;&#x6240;&#x6709;&#x65E5;&#x5FD7;&#x5185;&#x5BB9;&#x3002;</p>
<p>&#x6216;&#x8005;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4F7F;&#x7528; <code>--trace</code> &#x6807;&#x5FD7;&#xFF08;&#x6216;&#x5728; <code>application.properties</code> &#x4E2D;&#x7684;&#x8BBE;&#x7F6E; <code>trace=true</code>&#xFF09;&#x542F;&#x52A8;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x6765;&#x542F;&#x7528;<strong>&#x8DDF;&#x8E2A;</strong>&#x6A21;&#x5F0F;&#x3002;&#x8FD9;&#x6837;&#x505A;&#x53EF;&#x4EE5;&#x4E3A;&#x9009;&#x62E9;&#x7684;&#x6838;&#x5FC3;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5668;&#xFF08;&#x5185;&#x5D4C;&#x5BB9;&#x5668;&#x3001;Hibernate &#x6A21;&#x5F0F;&#x751F;&#x6210;&#x548C;&#x6574;&#x4E2A; Spring &#x7EC4;&#x5408;&#xFF09;&#x542F;&#x7528;&#x65E5;&#x5FD7;&#x8FFD;&#x8E2A;&#x3002;</p>
<p><a id="boot-features-logging-color-coded-output"></a></p>
<h3 id="2621&#x3001;&#x7740;&#x8272;&#x8F93;&#x51FA;">26.2.1&#x3001;&#x7740;&#x8272;&#x8F93;&#x51FA;</h3>
<p>&#x5982;&#x679C;&#x60A8;&#x7684;&#x7EC8;&#x7AEF;&#x652F;&#x6301; ANSI&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x989C;&#x8272;&#x8F93;&#x51FA;&#x6765;&#x63D0;&#x9AD8;&#x53EF;&#x8BFB;&#x6027;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x5C06; <code>spring.output.ansi.enabled</code> &#x8BBE;&#x7F6E;&#x4E3A;<a href="https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/api/org/springframework/boot/ansi/AnsiOutput.Enabled.html" target="_blank">&#x53D7;&#x652F;&#x6301;&#x7684;&#x503C;</a>&#x4EE5;&#x8986;&#x76D6;&#x81EA;&#x52A8;&#x68C0;&#x6D4B;&#x3002;</p>
<p>&#x53EF;&#x4F7F;&#x7528; <code>&#xFF05;clr</code> &#x8F6C;&#x6362;&#x5B57;&#x914D;&#x7F6E;&#x989C;&#x8272;&#x7F16;&#x7801;&#x3002;&#x6700;&#x7B80;&#x5355;&#x5F62;&#x5F0F;&#x662F;&#xFF0C;&#x8F6C;&#x6362;&#x5668;&#x6839;&#x636E;&#x65E5;&#x5FD7;&#x7EA7;&#x522B;&#x5BF9;&#x8F93;&#x51FA;&#x8FDB;&#x884C;&#x7740;&#x8272;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code>%clr(%5p)
</code></pre><p>&#x4E0B;&#x8868;&#x63CF;&#x8FF0;&#x65E5;&#x5FD7;&#x7EA7;&#x522B;&#x4E0E;&#x989C;&#x8272;&#x7684;&#x6620;&#x5C04;&#x5173;&#x7CFB;&#xFF1A;</p>
<table>
<thead>
<tr>
<th>&#x7EA7;&#x522B;</th>
<th>&#x989C;&#x8272;</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>FATAL</code></td>
<td>&#x7EA2;&#xFF08;Red&#xFF09;</td>
</tr>
<tr>
<td><code>ERROR</code></td>
<td>&#x7EA2;&#xFF08;Red&#xFF09;</td>
</tr>
<tr>
<td><code>WARN</code></td>
<td>&#x9EC4;&#xFF08;Yellow&#xFF09;</td>
</tr>
<tr>
<td><code>INFO</code></td>
<td>&#x7EFF;&#xFF08;Green&#xFF09;</td>
</tr>
<tr>
<td><code>DEBUG</code></td>
<td>&#x7EFF;&#xFF08;Green&#xFF09;</td>
</tr>
<tr>
<td><code>TRACE</code></td>
<td>&#x7EFF;&#xFF08;Green&#xFF09;</td>
</tr>
</tbody>
</table>
<p>&#x6216;&#x8005;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5C06;&#x5176;&#x4F5C;&#x4E3A;&#x8F6C;&#x6362;&#x9009;&#x9879;&#x6307;&#x5B9A;&#x5E94;&#x4F7F;&#x7528;&#x7684;&#x989C;&#x8272;&#x6216;&#x6837;&#x5F0F;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x8981;&#x5C06;&#x6587;&#x672C;&#x53D8;&#x4E3A;&#x9EC4;&#x8272;&#xFF0C;&#x8BF7;&#x4F7F;&#x7528;&#x4EE5;&#x4E0B;&#x8BBE;&#x7F6E;&#xFF1A;</p>
<pre class="language-"><code>%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}
</code></pre><p>&#x652F;&#x6301;&#x4EE5;&#x4E0B;&#x989C;&#x8272;&#x548C;&#x6837;&#x5F0F;&#xFF1A;</p>
<ul>
<li><code>blue</code></li>
<li><code>cyan</code></li>
<li><code>faint</code></li>
<li><code>green</code></li>
<li><code>magenta</code></li>
<li><code>red</code></li>
<li><code>yellow</code></li>
</ul>
<p><a id="boot-features-logging-file-output"></a></p>
<h3 id="263&#x3001;&#x6587;&#x4EF6;&#x8F93;&#x51FA;">26.3&#x3001;&#x6587;&#x4EF6;&#x8F93;&#x51FA;</h3>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Spring Boot &#x4EC5;&#x8BB0;&#x5F55;&#x5230;&#x63A7;&#x5236;&#x53F0;&#xFF0C;&#x4E0D;&#x4F1A;&#x5199;&#x5165;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;&#x3002;&#x60F3;&#x9664;&#x4E86;&#x63A7;&#x5236;&#x53F0;&#x8F93;&#x51FA;&#x4E4B;&#x5916;&#x8FD8;&#x8981;&#x5199;&#x5165;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;&#xFF0C;&#x5219;&#x9700;&#x8981;&#x8BBE;&#x7F6E; <code>logging.file</code> &#x6216; <code>logging.path</code> &#x5C5E;&#x6027;&#xFF08;&#x4F8B;&#x5982;&#xFF0C;&#x5728; <code>application.properties</code> &#x4E2D;&#xFF09;&#x3002;</p>
<p>&#x4E0B;&#x8868;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x4E0E; <code>logging.*</code> &#x5C5E;&#x6027;&#x4E00;&#x8D77;&#x4F7F;&#x7528;&#xFF1A;</p>
<p><strong>&#x8868; 26.1&#x3001;Logging &#x5C5E;&#x6027;</strong></p>
<table>
<thead>
<tr>
<th><code>logging.file</code></th>
<th><code>logging.path</code></th>
<th>&#x793A;&#x4F8B;</th>
<th>&#x63CF;&#x8FF0;</th>
</tr>
</thead>
<tbody>
<tr>
<td>&#xFF08;&#x65E0;&#xFF09;</td>
<td>&#xFF08;&#x65E0;&#xFF09;</td>
<td></td>
<td>&#x4EC5;&#x5728;&#x63A7;&#x5236;&#x53F0;&#x8F93;&#x51FA;</td>
</tr>
<tr>
<td>&#x6307;&#x5B9A;&#x6587;&#x4EF6;</td>
<td>(&#x65E0;)</td>
<td><code>my.log</code></td>
<td>&#x5199;&#x5165;&#x6307;&#x5B9A;&#x7684;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;&#x3002;&#x540D;&#x79F0;&#x53EF;&#x4EE5;&#x662F;&#x7EDD;&#x5BF9;&#x4F4D;&#x7F6E;&#x6216;&#x76F8;&#x5BF9;&#x4E8E;&#x5F53;&#x524D;&#x76EE;&#x5F55;&#x3002;</td>
</tr>
<tr>
<td>&#xFF08;&#x65E0;&#xFF09;</td>
<td>&#x6307;&#x5B9A;&#x76EE;&#x5F55;</td>
<td><code>/var/log</code></td>
<td>&#x5C06; <code>spring.log</code> &#x5199;&#x5165;&#x6307;&#x5B9A;&#x7684;&#x76EE;&#x5F55;&#x3002;&#x540D;&#x79F0;&#x53EF;&#x4EE5;&#x662F;&#x7EDD;&#x5BF9;&#x4F4D;&#x7F6E;&#x6216;&#x76F8;&#x5BF9;&#x4E8E;&#x5F53;&#x524D;&#x76EE;&#x5F55;&#x3002;</td>
</tr>
</tbody>
</table>
<p>&#x65E5;&#x5FD7;&#x6587;&#x4EF6;&#x5728;&#x8FBE;&#x5230; 10MB &#x65F6;&#x4F1A;&#x8F6E;&#x8F6C;&#xFF0C;&#x5E76;&#x4E14;&#x4E0E;&#x63A7;&#x5236;&#x53F0;&#x8F93;&#x51FA;&#x4E00;&#x6837;&#xFF0C;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#x4F1A;&#x8BB0;&#x5F55; <code>ERROR</code>&#x3001;<code>WARN</code> &#x548C; <code>INFO</code> &#x7EA7;&#x522B;&#x7684;&#x5185;&#x5BB9;&#x3002;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>logging.file.max-size</code> &#x5C5E;&#x6027;&#x66F4;&#x6539;&#x5927;&#x5C0F;&#x9650;&#x5236;&#x3002;&#x9664;&#x975E;&#x5DF2;&#x8BBE;&#x7F6E; <code>logging.file.max-history</code> &#x5C5E;&#x6027;&#xFF0C;&#x5426;&#x5219;&#x4EE5;&#x524D;&#x8F6E;&#x8F6C;&#x7684;&#x6587;&#x4EF6;&#x5C06;&#x65E0;&#x9650;&#x671F;&#x5F52;&#x6863;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x7CFB;&#x7EDF;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x751F;&#x547D;&#x5468;&#x671F;&#x7684;&#x65E9;&#x671F;&#x5F00;&#x59CB;&#x521D;&#x59CB;&#x5316;&#x3002;&#x56E0;&#x6B64;&#xFF0C;&#x901A;&#x8FC7; <code>@PropertySource</code> &#x6CE8;&#x89E3;&#x52A0;&#x8F7D;&#x7684;&#x5C5E;&#x6027;&#x6587;&#x4EF6;&#x4E2D;&#x662F;&#x627E;&#x4E0D;&#x5230;&#x65E5;&#x5FD7;&#x5C5E;&#x6027;&#x7684;&#x3002;</p>
</blockquote>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x65E5;&#x5FD7;&#x5C5E;&#x6027;&#x72EC;&#x7ACB;&#x4E8E;&#x5B9E;&#x9645;&#x7684;&#x65E5;&#x5FD7;&#x5E95;&#x5C42;&#x3002;&#x56E0;&#x6B64;&#xFF0C;spring Boot &#x4E0D;&#x7BA1;&#x7406;&#x7279;&#x5B9A;&#x7684;&#x914D;&#x7F6E; key&#xFF08;&#x4F8B;&#x5982; Logback &#x7684; <code>logback.configurationFile</code>&#xFF09;&#x3002;</p>
</blockquote>
<p><a id="boot-features-custom-log-levels"></a></p>
<h3 id="264&#x3001;&#x65E5;&#x5FD7;&#x7B49;&#x7EA7;">26.4&#x3001;&#x65E5;&#x5FD7;&#x7B49;&#x7EA7;</h3>
<p>&#x6240;&#x6709;&#x53D7;&#x652F;&#x6301;&#x7684;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x7CFB;&#x7EDF;&#x90FD;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>logging.level.<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>logger-name</span><span class="token punctuation">&gt;</span></span>=<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>level</span><span class="token punctuation">&gt;</span></span></code> &#x6765;&#x8BBE;&#x7F6E; Spring <code>Environment</code> &#x4E2D;&#x7684;&#x8BB0;&#x5F55;&#x5668;&#x7B49;&#x7EA7;&#xFF08;&#x4F8B;&#x5982;&#xFF0C;&#x5728; <code>application.properties</code> &#x4E2D;&#xFF09;&#x3002;&#x5176;&#x4E2D; <code>level</code> &#x662F; TRACE&#x3001;DEBUG&#x3001;INFO&#x3001;WARN&#x3001;ERROR&#x3001;FATAL &#x548C; OFF &#x5176;&#x4E2D;&#x4E4B;&#x4E00;&#x3002;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>logging.level.root</code> &#x914D;&#x7F6E; <code>root</code> &#x8BB0;&#x5F55;&#x5668;&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x4E86; <code>application.properties</code> &#x4E2D;&#x9ED8;&#x8BA4;&#x7684;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x8BBE;&#x7F6E;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">logging.level.root</span><span class="token attr-value"><span class="token punctuation">=</span>WARN</span>
<span class="token constant">logging.level.org.springframework.web</span><span class="token attr-value"><span class="token punctuation">=</span>DEBUG</span>
<span class="token constant">logging.level.org.hibernate</span><span class="token attr-value"><span class="token punctuation">=</span>ERROR</span>
</code></pre>
<p><a id="boot-features-custom-log-groups"></a></p>
<h3 id="265&#x3001;&#x65E5;&#x5FD7;&#x7EC4;">26.5&#x3001;&#x65E5;&#x5FD7;&#x7EC4;</h3>
<p>&#x5C06;&#x76F8;&#x5173;&#x8BB0;&#x5F55;&#x5668;&#x7EC4;&#x5408;&#x5728;&#x4E00;&#x8D77;&#x4EE5;&#x4FBF;&#x53EF;&#x4EE5;&#x540C;&#x65F6;&#x914D;&#x7F6E;&#xFF0C;&#x8FD9;&#x901A;&#x5E38;&#x5F88;&#x6709;&#x7528;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x66F4;&#x6539;<strong>&#x6240;&#x6709;</strong> Tomcat &#x76F8;&#x5173;&#x8BB0;&#x5F55;&#x5668;&#x7684;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x7EA7;&#x522B;&#xFF0C;&#x4F46;&#x60A8;&#x65E0;&#x6CD5;&#x8F7B;&#x677E;&#x8BB0;&#x4F4F;&#x9876;&#x5C42;&#x7684;&#x5305;&#x540D;&#x3002;</p>
<p>&#x4E3A;&#x4E86;&#x89E3;&#x51B3;&#x8FD9;&#x4E2A;&#x95EE;&#x9898;&#xFF0C;Spring Boot &#x5141;&#x8BB8;&#x60A8;&#x5728; Spring <code>Environment</code> &#x4E2D;&#x5B9A;&#x4E49;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x7EC4;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x4EE5;&#x4E0B;&#x901A;&#x8FC7;&#x5C06; <strong>tomcat</strong> &#x7EC4;&#x6DFB;&#x52A0;&#x5230; <code>application.properties</code> &#x6765;&#x5B9A;&#x4E49; <strong>tomcat</strong> &#x7EC4;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">logging.group.tomcat</span><span class="token attr-value"><span class="token punctuation">=</span>org.apache.catalina, org.apache.coyote, org.apache.tomcat</span>
</code></pre>
<p>&#x5B9A;&#x4E49;&#x540E;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4E00;&#x884C;&#x914D;&#x7F6E;&#x6765;&#x66F4;&#x6539;&#x7EC4;&#x4E2D;&#x6240;&#x6709;&#x8BB0;&#x5F55;&#x5668;&#x7684;&#x7EA7;&#x522B;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">logging.level.tomcat</span><span class="token attr-value"><span class="token punctuation">=</span>TRACE</span>
</code></pre>
<p>Spring Boot &#x5305;&#x542B;&#x4EE5;&#x4E0B;&#x9884;&#x5B9A;&#x4E49;&#x7684;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x7EC4;&#xFF0C;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x4F7F;&#x7528;&#xFF1A;</p>
<table>
<thead>
<tr>
<th>&#x540D;&#x79F0;</th>
<th>&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5668;</th>
</tr>
</thead>
<tbody>
<tr>
<td>web</td>
<td><code>org.springframework.core.codec</code>&#x3001;<code>org.springframework.http</code>&#x3001;<code>org.springframework.web</code></td>
</tr>
<tr>
<td>sql</td>
<td><code>org.springframework.jdbc.core</code>&#x3001;<code>org.hibernate.SQL</code></td>
</tr>
</tbody>
</table>
<p><a id="boot-features-custom-log-configuration"></a></p>
<h3 id="266&#x3001;&#x81EA;&#x5B9A;&#x4E49;&#x65E5;&#x5FD7;&#x914D;&#x7F6E;">26.6&#x3001;&#x81EA;&#x5B9A;&#x4E49;&#x65E5;&#x5FD7;&#x914D;&#x7F6E;</h3>
<p>&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5728; classpath &#x4E2D;&#x5F15;&#x5165;&#x9002;&#x5408;&#x7684;&#x5E93;&#x6765;&#x6FC0;&#x6D3B;&#x5404;&#x79CD;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x7CFB;&#x7EDF;&#xFF0C;&#x5E76;&#x4E14;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5728; classpath &#x7684;&#x6839;&#x76EE;&#x5F55;&#x4E2D;&#x6216;&#x5728;&#x4EE5;&#x4E0B; Spring <code>Environment</code> &#x5C5E;&#x6027;&#x6307;&#x5B9A;&#x7684;&#x4F4D;&#x7F6E;&#x63D0;&#x4F9B;&#x5408;&#x9002;&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x6765;&#x8FDB;&#x4E00;&#x6B65;&#x81EA;&#x5B9A;&#x4E49;&#xFF1A;<code>logging.config</code>&#x3002;</p>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>org.springframework.boot.logging.LoggingSystem</code> &#x7CFB;&#x7EDF;&#x5C5E;&#x6027;&#x5F3A;&#x5236; Spring Boot &#x4F7F;&#x7528;&#x7279;&#x5B9A;&#x7684;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x7CFB;&#x7EDF;&#x3002;&#x8BE5;&#x503C;&#x5E94;&#x8BE5;&#x662F;&#x4E00;&#x4E2A;&#x5B9E;&#x73B0;&#x4E86; <code>LoggingSystem</code> &#x7684;&#x7C7B;&#x7684;&#x5B8C;&#x5168;&#x9650;&#x5B9A;&#x7C7B;&#x540D;&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>none</code> &#x503C;&#x5B8C;&#x5168;&#x7981;&#x7528; Spring Boot &#x7684;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x914D;&#x7F6E;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x7531;&#x4E8E;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5728;&#x521B;&#x5EFA; <code>ApplicationContext</code> &#x4E4B;&#x524D;&#x521D;&#x59CB;&#x5316;&#xFF0C;&#x56E0;&#x6B64;&#x65E0;&#x6CD5;&#x5728; Spring <code>@Configuration</code> &#x6587;&#x4EF6;&#x4E2D;&#x63A7;&#x5236;&#x6765;&#x81EA; <code>@PropertySources</code> &#x7684;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x3002;&#x66F4;&#x6539;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x7CFB;&#x7EDF;&#x6216;&#x5B8C;&#x5168;&#x7981;&#x7528;&#x5B83;&#x7684;&#x552F;&#x4E00;&#x65B9;&#x6CD5;&#x662F;&#x901A;&#x8FC7;&#x7CFB;&#x7EDF;&#x5C5E;&#x6027;&#x8BBE;&#x7F6E;&#x3002;</p>
</blockquote>
<p>&#x6839;&#x636E;&#x60A8;&#x7684;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x7CFB;&#x7EDF;&#xFF0C;&#x5C06;&#x52A0;&#x8F7D;&#x4EE5;&#x4E0B;&#x6587;&#x4EF6;&#xFF1A;</p>
<table>
<thead>
<tr>
<th>&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x7CFB;&#x7EDF;</th>
<th>&#x6587;&#x4EF6;</th>
</tr>
</thead>
<tbody>
<tr>
<td>Logback</td>
<td><code>logback-spring.xml</code>&#x3001;<code>logback-spring.groovy</code>&#x3001;<code>logback.xml</code> &#x6216;&#x8005; <code>logback.groovy</code></td>
</tr>
<tr>
<td>Log4j2</td>
<td><code>log4j2-spring.xml</code> &#x6216;&#x8005; <code>log4j2.xml</code></td>
</tr>
<tr>
<td>JDK&#xFF08;Java Util Logging&#xFF09;</td>
<td><code>logging.properties</code></td>
</tr>
</tbody>
</table>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x53EF;&#x80FD;&#xFF0C;&#x6211;&#x4EEC;&#x5EFA;&#x8BAE;&#x60A8;&#x4F7F;&#x7528; <code>-spring</code> &#x7684;&#x5F62;&#x5F0F;&#x6765;&#x914D;&#x7F6E;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#xFF08;&#x6BD4;&#x5982; <code>logback-spring.xml</code> &#x800C;&#x4E0D;&#x662F; <code>logback.xml</code>&#xFF09;&#x3002;&#x5982;&#x679C;&#x4F7F;&#x7528;&#x6807;&#x51C6;&#x7684;&#x914D;&#x7F6E;&#x4F4D;&#x7F6E;&#xFF0C;Spring &#x65E0;&#x6CD5;&#x5B8C;&#x5168;&#x63A7;&#x5236;&#x65E5;&#x5FD7;&#x521D;&#x59CB;&#x5316;&#x3002;</p>
</blockquote>
<p><strong>&#x8B66;&#x544A;</strong></p>
<blockquote>
<p>Java Util Logging &#x5B58;&#x5728;&#x5DF2;&#x77E5;&#x7684;&#x7C7B;&#x52A0;&#x8F7D;&#x95EE;&#x9898;&#xFF0C;&#x8FD9;&#x4E9B;&#x95EE;&#x9898;&#x5728;&#x4EE5;<strong>&#x53EF;&#x6267;&#x884C; jar</strong> &#x8FD0;&#x884C;&#x65F6;&#x4F1A;&#x89E6;&#x53D1;&#x3002;&#x5982;&#x679C;&#x53EF;&#x80FD;&#x7684;&#x8BDD;&#xFF0C;&#x6211;&#x4EEC;&#x5EFA;&#x8BAE;&#x60A8;&#x5728;&#x4F7F;&#x7528;<strong>&#x53EF;&#x6267;&#x884C; jar</strong> &#x65B9;&#x5F0F;&#x8FD0;&#x884C;&#x65F6;&#x907F;&#x514D;&#x4F7F;&#x7528;&#x5B83;&#x3002;</p>
</blockquote>
<p>&#x4E3A;&#x4E86;&#x8FDB;&#x884C;&#x81EA;&#x5B9A;&#x4E49;&#xFF0C;&#x90E8;&#x5206;&#x5176;&#x4ED6;&#x5C5E;&#x6027;&#x4F1A;&#x4ECE; Spring <code>Environment</code> &#x4F20;&#x8F93;&#x5230; System &#x5C5E;&#x6027;&#xFF0C;&#x5982;&#x4E0B;&#x8868;&#x6240;&#x8FF0;&#xFF1A;</p>
<table>
<thead>
<tr>
<th>Spring Environment</th>
<th>&#x7CFB;&#x7EDF;&#x5C5E;&#x6027;</th>
<th>&#x8BF4;&#x660E;</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>logging.exception-conversion-word</code></td>
<td><code>LOG_EXCEPTION_CONVERSION_WORD</code></td>
<td>&#x8BB0;&#x5F55;&#x5F02;&#x5E38;&#x65F6;&#x4F7F;&#x7528;&#x7684;&#x8F6C;&#x6362;&#x5B57;&#x3002;</td>
</tr>
<tr>
<td><code>logging.file</code></td>
<td><code>LOG_FILE</code></td>
<td>&#x5982;&#x679C;&#x5DF2;&#x5B9A;&#x4E49;&#xFF0C;&#x5219;&#x5728;&#x9ED8;&#x8BA4;&#x65E5;&#x5FD7;&#x914D;&#x7F6E;&#x4E2D;&#x4F7F;&#x7528;&#x5B83;&#x3002;</td>
</tr>
<tr>
<td><code>logging.file.max-size</code></td>
<td><code>LOG_FILE_MAX_SIZE</code></td>
<td>&#x6700;&#x5927;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;&#x5927;&#x5C0F;&#xFF08;&#x5982;&#x679C;&#x542F;&#x7528;&#x4E86; LOG_FILE&#xFF09;&#x3002;&#xFF08;&#x4EC5;&#x652F;&#x6301;&#x9ED8;&#x8BA4;&#x7684; Logback &#x8BBE;&#x7F6E;&#x3002;&#xFF09;</td>
</tr>
<tr>
<td><code>logging.file.max-history</code></td>
<td><code>LOG_FILE_MAX_HISTORY</code></td>
<td>&#x8981;&#x4FDD;&#x7559;&#x7684;&#x5F52;&#x6863;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;&#x6700;&#x5927;&#x6570;&#x91CF;&#xFF08;&#x5982;&#x679C;&#x542F;&#x7528;&#x4E86; LOG_FILE&#xFF09;&#x3002;&#xFF08;&#x4EC5;&#x652F;&#x6301;&#x9ED8;&#x8BA4;&#x7684; Logback &#x8BBE;&#x7F6E;&#x3002;&#xFF09;</td>
</tr>
<tr>
<td><code>logging.path</code></td>
<td><code>LOG_PATH</code></td>
<td>&#x5982;&#x679C;&#x5DF2;&#x5B9A;&#x4E49;&#xFF0C;&#x5219;&#x5728;&#x9ED8;&#x8BA4;&#x65E5;&#x5FD7;&#x914D;&#x7F6E;&#x4E2D;&#x4F7F;&#x7528;&#x5B83;&#x3002;</td>
</tr>
<tr>
<td><code>logging.pattern.console</code></td>
<td><code>CONSOLE_LOG_PATTERN</code></td>
<td>&#x8981;&#x5728;&#x63A7;&#x5236;&#x53F0;&#x4E0A;&#x4F7F;&#x7528;&#x7684;&#x65E5;&#x5FD7;&#x6A21;&#x5F0F;&#xFF08;stdout&#xFF09;&#x3002;&#xFF08;&#x4EC5;&#x652F;&#x6301;&#x9ED8;&#x8BA4;&#x7684; Logback &#x8BBE;&#x7F6E;&#x3002;&#xFF09;</td>
</tr>
<tr>
<td><code>logging.pattern.dateformat</code></td>
<td><code>LOG_DATEFORMAT_PATTERN</code></td>
<td>&#x65E5;&#x5FD7;&#x65E5;&#x671F;&#x683C;&#x5F0F;&#x7684; Appender &#x6A21;&#x5F0F;&#x3002;&#xFF08;&#x4EC5;&#x652F;&#x6301;&#x9ED8;&#x8BA4;&#x7684; Logback &#x8BBE;&#x7F6E;&#x3002;&#xFF09;</td>
</tr>
<tr>
<td><code>logging.pattern.file</code></td>
<td><code>FILE_LOG_PATTERN</code></td>
<td>&#x8981;&#x5728;&#x6587;&#x4EF6;&#x4E2D;&#x4F7F;&#x7528;&#x7684;&#x65E5;&#x5FD7;&#x6A21;&#x5F0F;&#xFF08;&#x5982;&#x679C;&#x542F;&#x7528;&#x4E86; <code>LOG_FILE</code>&#xFF09;&#x3002;&#xFF08;&#x4EC5;&#x652F;&#x6301;&#x9ED8;&#x8BA4;&#x7684; Logback &#x8BBE;&#x7F6E;&#x3002;&#xFF09;</td>
</tr>
<tr>
<td><code>logging.pattern.level</code></td>
<td><code>LOG_LEVEL_PATTERN</code></td>
<td>&#x6E32;&#x67D3;&#x65E5;&#x5FD7;&#x7EA7;&#x522B;&#x65F6;&#x4F7F;&#x7528;&#x7684;&#x683C;&#x5F0F;&#xFF08;&#x9ED8;&#x8BA4;&#x503C;&#x4E3A; <code>&#xFF05;5p</code>&#xFF09;&#x3002;&#xFF08;&#x4EC5;&#x652F;&#x6301;&#x9ED8;&#x8BA4;&#x7684; Logback &#x8BBE;&#x7F6E;&#x3002;&#xFF09;</td>
</tr>
<tr>
<td><code>PID</code></td>
<td><code>PID</code></td>
<td>&#x5F53;&#x524D;&#x8FDB;&#x7A0B; ID&#xFF08;&#x5982;&#x679C;&#x53EF;&#x80FD;&#xFF0C;&#x5219;&#x5728;&#x672A;&#x5B9A;&#x4E49;&#x4E3A; OS &#x73AF;&#x5883;&#x53D8;&#x91CF;&#x65F6;&#x53D1;&#x73B0;&#xFF09;&#x3002;</td>
</tr>
</tbody>
</table>
<p>&#x6240;&#x6709;&#x53D7;&#x652F;&#x6301;&#x7684;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x7CFB;&#x7EDF;&#x5728;&#x89E3;&#x6790;&#x5176;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x65F6;&#x90FD;&#x53EF;&#x4EE5;&#x53C2;&#x8003;&#x7CFB;&#x7EDF;&#x5C5E;&#x6027;&#x3002;&#x6709;&#x5173;&#x793A;&#x4F8B;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <code>spring-boot.jar</code> &#x4E2D;&#x7684;&#x9ED8;&#x8BA4;&#x914D;&#x7F6E;&#xFF1A;</p>
<ul>
<li><a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml" target="_blank">Logback</a></li>
<li><a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml" target="_blank">Log4j 2</a></li>
<li><a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging-file.properties" target="_blank">Java Util logging</a></li>
</ul>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x8981;&#x5728;&#x65E5;&#x5FD7;&#x8BB0;&#x5F55;&#x5C5E;&#x6027;&#x4E2D;&#x4F7F;&#x7528;&#x5360;&#x4F4D;&#x7B26;&#xFF0C;&#x5219;&#x5E94;&#x4F7F;&#x7528; <a href="#boot-features-external-config-placeholders-in-properties">Spring Boot &#x7684;&#x8BED;&#x6CD5;</a>&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x4F7F;&#x7528;&#x5E95;&#x5C42;&#x6846;&#x67B6;&#x7684;&#x8BED;&#x6CD5;&#x3002;&#x503C;&#x5F97;&#x6CE8;&#x610F;&#x7684;&#x662F;&#xFF0C;&#x5982;&#x679C;&#x4F7F;&#x7528; Logback&#xFF0C;&#x5219;&#x5E94;&#x4F7F;&#x7528; <code>:</code> &#x4F5C;&#x4E3A;&#x5C5E;&#x6027;&#x540D;&#x79F0;&#x4E0E;&#x5176;&#x9ED8;&#x8BA4;&#x503C;&#x4E4B;&#x95F4;&#x7684;&#x5206;&#x9694;&#x7B26;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x4F7F;&#x7528; <code>:-</code>&#x3002;</p>
</blockquote>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>

&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4EC5;&#x8986;&#x76D6; `LOG_LEVEL_PATTERN`&#xFF08;&#x6216;&#x5E26; Logback &#x7684; `logging.pattern.level`&#xFF09;&#x5C06; MDC &#x548C;&#x5176;&#x4ED6;&#x7279;&#x522B;&#x7684;&#x5185;&#x5BB9;&#x6DFB;&#x52A0;&#x5230;&#x65E5;&#x5FD7;&#x884C;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5982;&#x679C;&#x4F7F;&#x7528; `logging.pattern.level=user:%X{user} %5p`&#xFF0C;&#x5219;&#x9ED8;&#x8BA4;&#x65E5;&#x5FD7;&#x683C;&#x5F0F;&#x5305;&#x542B; **user** MDC &#x9879;&#xFF08;&#x5982;&#x679C;&#x5B58;&#x5728;&#xFF09;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;:

```
2015-09-30 12:30:04.031 user:someone INFO 22174 --- [  nio-8080-exec-0] demo.Controller
Handling authenticated request
```

</blockquote>

<p><a id="boot-features-logback-extensions"></a></p>
<h3 id="267&#x3001;logback-&#x6269;&#x5C55;">26.7&#x3001;Logback &#x6269;&#x5C55;</h3>
<p>Spring Boot &#x5305;&#x542B;&#x8BB8;&#x591A; Logback &#x6269;&#x5C55;&#xFF0C;&#x53EF;&#x7528;&#x4E8E;&#x8FDB;&#x884C;&#x9AD8;&#x7EA7;&#x914D;&#x7F6E;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>logback-spring.xml</code> &#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4E2D;&#x4F7F;&#x7528;&#x8FD9;&#x4E9B;&#x6269;&#x5C55;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x7531;&#x4E8E;&#x6807;&#x51C6;&#x7684; logback.xml &#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x52A0;&#x8F7D;&#x8FC7;&#x65E9;&#xFF0C;&#x56E0;&#x6B64;&#x65E0;&#x6CD5;&#x5728;&#x5176;&#x4E2D;&#x4F7F;&#x7528;&#x6269;&#x5C55;&#x3002;&#x60A8;&#x9700;&#x8981;&#x4F7F;&#x7528; <code>logback-spring.xml</code> &#x6216;&#x5B9A;&#x4E49; <code>logging.config</code> &#x5C5E;&#x6027;&#x3002;</p>
</blockquote>
<p><strong>&#x8B66;&#x544A;</strong></p>
<blockquote>
<p>&#x6269;&#x5C55;&#x4E0D;&#x80FD;&#x4E0E; Logback &#x7684;<a href="http://logback.qos.ch/manual/configuration.html#autoScan" target="_blank">&#x914D;&#x7F6E;&#x626B;&#x63CF;</a>&#x4E00;&#x8D77;&#x4F7F;&#x7528;&#x3002;&#x5982;&#x679C;&#x5C1D;&#x8BD5;&#x8FD9;&#x6837;&#x505A;&#xFF0C;&#x66F4;&#x6539;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4F1A;&#x5BFC;&#x81F4;&#x53D1;&#x751F;&#x7C7B;&#x4F3C;&#x4EE5;&#x4E0B;&#x9519;&#x8BEF;&#x65E5;&#x5FD7;&#xFF1A;</p>
</blockquote>
<pre class="language-"><code>ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]
</code></pre><p><a id="_profile_specific_configuration"></a></p>
<h3 id="2671&#x3001;&#x7279;&#x5B9A;-profile-&#x914D;&#x7F6E;">26.7.1&#x3001;&#x7279;&#x5B9A; Profile &#x914D;&#x7F6E;</h3>
<p><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>springProfile</span><span class="token punctuation">&gt;</span></span></code> &#x6807;&#x7B7E;&#x5141;&#x8BB8;&#x60A8;&#x6839;&#x636E;&#x6FC0;&#x6D3B;&#x7684; Spring profile &#x9009;&#x62E9;&#x6027;&#x5730;&#x5305;&#x542B;&#x6216;&#x6392;&#x9664;&#x914D;&#x7F6E;&#x90E8;&#x5206;&#x3002;&#x5728; <code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>configuration</span><span class="token punctuation">&gt;</span></span></code> &#x5143;&#x7D20;&#x4E2D;&#x7684;&#x4EFB;&#x4F55;&#x4F4D;&#x7F6E;&#x90FD;&#x652F;&#x6301;&#x914D;&#x7F6E; profile&#x3002;&#x4F7F;&#x7528; <code>name</code> &#x5C5E;&#x6027;&#x6307;&#x5B9A;&#x54EA;&#x4E2A; proifle &#x63A5;&#x53D7;&#x914D;&#x7F6E;&#x3002;<code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>springProfile</span><span class="token punctuation">&gt;</span></span></code> &#x6807;&#x8BB0;&#x53EF;&#x4EE5;&#x5305;&#x542B;&#x7B80;&#x5355;&#x7684; proifle &#x540D;&#x79F0;&#xFF08;&#x4F8B;&#x5982; <code>staging</code>&#xFF09;&#x6216; profile &#x8868;&#x8FBE;&#x5F0F;&#x3002;profile &#x8868;&#x8FBE;&#x5F0F;&#x5141;&#x8BB8;&#x8868;&#x8FBE;&#x66F4;&#x590D;&#x6742;&#x7684; profile &#x903B;&#x8F91;&#xFF0C;&#x4F8B;&#x5982; <code>production &amp; (eu-central | eu-west)</code>&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x67E5;&#x9605;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/core.html#beans-definition-profiles-java" target="_blank">&#x53C2;&#x8003;&#x6307;&#x5357;</a>&#x3002;&#x4EE5;&#x4E0B;&#x6E05;&#x5355;&#x5C55;&#x793A;&#x4E86;&#x4E09;&#x4E2A;&#x793A;&#x4F8B; profile&#xFF1A;</p>
<pre class="language-"><code class="lang-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>springProfile</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>staging<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- configuration to be enabled when the &quot;staging&quot; profile is active --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>springProfile</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>springProfile</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>dev | staging<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- configuration to be enabled when the &quot;dev&quot; or &quot;staging&quot; profiles are active --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>springProfile</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>springProfile</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>!production<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token comment">&lt;!-- configuration to be enabled when the &quot;production&quot; profile is not active --&gt;</span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>springProfile</span><span class="token punctuation">&gt;</span></span>
</code></pre>
<p><a id="_environment_properties"></a></p>
<h3 id="2672&#x3001;&#x73AF;&#x5883;&#x5C5E;&#x6027;">26.7.2&#x3001;&#x73AF;&#x5883;&#x5C5E;&#x6027;</h3>
<p>&#x4F7F;&#x7528; <code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>springProperty</span><span class="token punctuation">&gt;</span></span></code> &#x6807;&#x8BB0;&#x53EF;&#x4EE5;&#x8BA9;&#x60A8;&#x66B4;&#x9732; Spring &#x73AF;&#x5883;&#xFF08;<code>Environment</code>&#xFF09;&#x4E2D;&#x7684;&#x5C5E;&#x6027;&#xFF0C;&#x4EE5;&#x4FBF;&#x5728; Logback &#x4E2D;&#x4F7F;&#x7528;&#x3002;&#x5982;&#x679C;&#x5728; Logback &#x914D;&#x7F6E;&#x4E2D;&#x8BBF;&#x95EE;&#x6765;&#x81EA; <code>application.properties</code> &#x6587;&#x4EF6;&#x7684;&#x503C;&#xFF0C;&#x8FD9;&#x6837;&#x505A;&#x5F88;&#x6709;&#x7528;&#x3002;&#x6807;&#x7B7E;&#x7684;&#x5DE5;&#x4F5C;&#x65B9;&#x5F0F;&#x4E0E; Logback &#x7684;&#x6807;&#x51C6; <code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>property</span><span class="token punctuation">&gt;</span></span></code> &#x6807;&#x7B7E;&#x7C7B;&#x4F3C;&#x3002;&#x4F46;&#x662F;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x6307;&#x5B9A;&#x5C5E;&#x6027;&#xFF08;&#x6765;&#x81EA; <code>Environment</code>&#xFF09;&#x7684; <code>source</code>&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x6307;&#x5B9A;&#x76F4;&#x63A5;&#x7684; <code>value</code>&#x3002;&#x5982;&#x679C;&#x9700;&#x8981;&#x5C06;&#x5C5E;&#x6027;&#x5B58;&#x50A8;&#x5728; <code>local</code> &#x8303;&#x56F4;&#x4EE5;&#x5916;&#x7684;&#x5176;&#x4ED6;&#x4F4D;&#x7F6E;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>scope</code> &#x5C5E;&#x6027;&#x3002;&#x5982;&#x679C;&#x9700;&#x8981;&#x56DE;&#x9000;&#x503C;&#xFF08;&#x5982;&#x679C;&#x672A;&#x5728; <code>Environment</code> &#x4E2D;&#x8BBE;&#x7F6E;&#x8BE5;&#x5C5E;&#x6027;&#xFF09;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>defaultValue</code> &#x5C5E;&#x6027;&#x3002;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x66B4;&#x9732;&#x5C5E;&#x6027;&#x4EE5;&#x4FBF;&#x5728; Logback &#x4E2D;&#x4F7F;&#x7528;&#xFF1A;</p>
<pre class="language-"><code class="lang-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>springProperty</span> <span class="token attr-name">scope</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>context<span class="token punctuation">&quot;</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>fluentHost<span class="token punctuation">&quot;</span></span> <span class="token attr-name">source</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>myapp.fluentd.host<span class="token punctuation">&quot;</span></span>
        <span class="token attr-name">defaultValue</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>localhost<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>appender</span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>FLUENT<span class="token punctuation">&quot;</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>ch.qos.logback.more.appenders.DataFluentAppender<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>remoteHost</span><span class="token punctuation">&gt;</span></span>${fluentHost}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>remoteHost</span><span class="token punctuation">&gt;</span></span>
    ...
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>appender</span><span class="token punctuation">&gt;</span></span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5FC5;&#x987B;&#x4EE5; kebab &#x98CE;&#x683C;&#xFF08;&#x77ED;&#x6A2A;&#x7EBF;&#x5C0F;&#x5199;&#x98CE;&#x683C;&#xFF09;&#x6307;&#x5B9A; <code>source</code>&#xFF08;&#x4F8B;&#x5982; <code>my.property-name</code>&#xFF09;&#x3002;&#x4F46;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x5BBD;&#x677E;&#x89C4;&#x5219;&#x5C06;&#x5C5E;&#x6027;&#x6DFB;&#x52A0;&#x5230; <code>Environment</code> &#x4E2D;&#x3002;</p>
</blockquote>
<p><a id="boot-features-json"></a></p>
<h2 id="27&#x3001;json">27&#x3001;JSON</h2>
<p>Spring Boot &#x4E3A;&#x4E09;&#x4E2A; JSON &#x6620;&#x5C04;&#x5E93;&#x63D0;&#x4F9B;&#x4E86;&#x5185;&#x7F6E;&#x96C6;&#x6210;&#xFF1A;</p>
<ul>
<li>GSON</li>
<li>Jackson</li>
<li>JSON-B</li>
</ul>
<p>Jackson &#x662F;&#x9996;&#x9009;&#x548C;&#x9ED8;&#x8BA4;&#x7684;&#x5E93;&#x3002;</p>
<p><a id="boot-features-json-jackson"></a></p>
<h2 id="271&#x3001;jackson">27.1&#x3001;Jackson</h2>
<p>Spring Boot &#x63D0;&#x4F9B;&#x4E86; Jackson &#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;Jackson &#x662F; <code>spring-boot-starter-json</code> &#x7684;&#x4E00;&#x90E8;&#x5206;&#x3002;&#x5F53; Jackson &#x5728; classpath &#x4E0A;&#x65F6;&#xFF0C;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E; <code>ObjectMapper</code> bean&#x3002;Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x51E0;&#x4E2A;&#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x6765;<a href="howto.md#howto-customize-the-jackson-objectmapper">&#x81EA;&#x5B9A;&#x4E49; <code>ObjectMapper</code> &#x7684;&#x914D;&#x7F6E;</a>&#x3002;</p>
<p><a id="boot-features-json-gson"></a></p>
<h2 id="272&#x3001;gson">27.2&#x3001;Gson</h2>
<p>Spring Boot &#x63D0;&#x4F9B; Gson &#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x5F53; Gson &#x5728; classpath &#x4E0A;&#x65F6;&#xFF0C;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E; <code>Gson</code> bean&#x3002;Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x51E0;&#x4E2A; <code>spring.gson.*</code> &#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x6765;&#x81EA;&#x5B9A;&#x4E49;&#x914D;&#x7F6E;&#x3002;&#x4E3A;&#x4E86;&#x83B7;&#x5F97;&#x66F4;&#x591A;&#x63A7;&#x5236;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x6216;&#x591A;&#x4E2A; <code>GsonBuilderCustomizer</code> bean&#x3002;</p>
<p><a id="boot-features-json-json-b"></a></p>
<h2 id="273&#x3001;json-b">27.3&#x3001;JSON-B</h2>
<p>Spring Boot &#x63D0;&#x4F9B;&#x4E86; JSON-B &#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x5F53; JSON-B API &#x548C;&#x5B9E;&#x73B0;&#x5728; classpath &#x4E0A;&#x65F6;&#xFF0C;&#x5C06;&#x81EA;&#x52A8;&#x914D;&#x7F6E; <code>Jsonb</code> bean&#x3002;&#x9996;&#x9009;&#x7684; JSON-B &#x5B9E;&#x73B0;&#x662F; Apache Johnzon&#xFF0C;&#x5B83;&#x63D0;&#x4F9B;&#x4E86;&#x4F9D;&#x8D56;&#x7BA1;&#x7406;&#x3002;</p>
<p><a id="boot-features-developing-web-applications"></a></p>
<h2 id="28&#x3001;&#x5F00;&#x53D1;-web-&#x5E94;&#x7528;&#x7A0B;&#x5E8F;">28&#x3001;&#x5F00;&#x53D1; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;</h2>
<p>Spring Boot &#x975E;&#x5E38;&#x9002;&#x5408;&#x7528;&#x4E8E;&#x5F00;&#x53D1; web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x5D4C;&#x5165;&#x5F0F; Tomcat&#x3001;Jetty &#x6216;&#x8005; Undertow &#x6765;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x72EC;&#x7ACB;&#xFF08;self-contained&#xFF09;&#x7684; HTTP &#x670D;&#x52A1;&#x5668;&#x3002;&#x5927;&#x591A;&#x6570; web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4F7F;&#x7528; <code>spring-boot-starter-web</code> &#x6A21;&#x5757;&#x6765;&#x5FEB;&#x901F;&#x642D;&#x5EFA;&#x548C;&#x8FD0;&#x884C;&#xFF0C;&#x60A8;&#x4E5F;&#x53EF;&#x4EE5;&#x9009;&#x62E9;&#x4F7F;&#x7528; <code>spring-boot-starter-webflux</code> &#x6A21;&#x5757;&#x6765;&#x6784;&#x5EFA;&#x54CD;&#x5E94;&#x5F0F;&#xFF08;reactive&#xFF09; web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x5C1A;&#x672A;&#x5F00;&#x53D1;&#x8FC7; Spring Boot web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x6309;&#x7167;<a href="#getting-started-first-application">&#x5165;&#x95E8;</a>&#x7AE0;&#x8282;&#x4E2D;&#x7684;&#x201C;Hello World!&#x201D;&#x793A;&#x4F8B;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;&#x3002;</p>
<p><a id="boot-features-spring-mvc"></a></p>
<h3 id="281&#x3001;spring-web-mvc-&#x6846;&#x67B6;">28.1&#x3001;Spring Web MVC &#x6846;&#x67B6;</h3>
<p><a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#mvc" target="_blank">Spring Web MVC &#x6846;&#x67B6;</a>&#xFF08;&#x901A;&#x5E38;&#x7B80;&#x79F0;&#x201C;Spring MVC&#x201D;&#xFF09;&#x662F;&#x4E00;&#x4E2A;&#x5BCC;<strong>&#x6A21;&#x578B;-&#x89C6;&#x56FE;-&#x63A7;&#x5236;&#x5668;</strong>&#x7684; web &#x6846;&#x67B6;&#x3002;Spring MVC &#x5141;&#x8BB8;&#x60A8;&#x521B;&#x5EFA; <code>@Controller</code> &#x6216;&#x8005; <code>@RestController</code> bean &#x6765;&#x5904;&#x7406;&#x4F20;&#x5165;&#x7684; HTTP &#x8BF7;&#x6C42;&#x3002;&#x63A7;&#x5236;&#x5668;&#x4E2D;&#x7684;&#x65B9;&#x6CD5;&#x901A;&#x8FC7; <code>@RequestMapping</code> &#x6CE8;&#x89E3;&#x6620;&#x5C04;&#x5230; HTTP&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x662F;&#x4E00;&#x4E2A;&#x4F7F;&#x7528;&#x4E86; <code>@RestController</code> &#x6765;&#x54CD;&#x5E94; JSON &#x6570;&#x636E;&#x7684;&#x5178;&#x578B;&#x793A;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@RestController</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">&quot;/users&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyRestController</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">&quot;/{user}&quot;</span><span class="token punctuation">,</span> method<span class="token operator">=</span><span class="token class-name">RequestMethod</span><span class="token punctuation">.</span>GET<span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">User</span> <span class="token function">getUser</span><span class="token punctuation">(</span><span class="token annotation punctuation">@PathVariable</span> <span class="token class-name">Long</span> user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">&quot;/{user}/customers&quot;</span><span class="token punctuation">,</span> method<span class="token operator">=</span><span class="token class-name">RequestMethod</span><span class="token punctuation">.</span>GET<span class="token punctuation">)</span>
    <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Customer</span><span class="token punctuation">&gt;</span></span> <span class="token function">getUserCustomers</span><span class="token punctuation">(</span><span class="token annotation punctuation">@PathVariable</span> <span class="token class-name">Long</span> user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value<span class="token operator">=</span><span class="token string">&quot;/{user}&quot;</span><span class="token punctuation">,</span> method<span class="token operator">=</span><span class="token class-name">RequestMethod</span><span class="token punctuation">.</span>DELETE<span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">User</span> <span class="token function">deleteUser</span><span class="token punctuation">(</span><span class="token annotation punctuation">@PathVariable</span> <span class="token class-name">Long</span> user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>Spring MVC &#x662F; Spring Framework &#x6838;&#x5FC3;&#x7684;&#x4E00;&#x90E8;&#x5206;&#xFF0C;&#x8BE6;&#x7EC6;&#x4ECB;&#x7ECD;&#x53EF;&#x53C2;&#x8003;&#x5176;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#mvc" target="_blank">&#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x3002;<a href="https://spring.io/guides" target="_blank">spring.io/guides</a> &#x8FD8;&#x63D0;&#x4F9B;&#x4E86;&#x51E0;&#x4E2A; Spring MVC &#x76F8;&#x5173;&#x7684;&#x6307;&#x5357;&#x3002;</p>
<p><a id="boot-features-spring-mvc-auto-configuration"></a></p>
<h4 id="2811&#x3001;spring-mvc-&#x81EA;&#x52A8;&#x914D;&#x7F6E;">28.1.1&#x3001;Spring MVC &#x81EA;&#x52A8;&#x914D;&#x7F6E;</h4>
<p>Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x9002;&#x7528;&#x4E8E;&#x5927;&#x591A;&#x6570; Spring MVC &#x5E94;&#x7528;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF08;auto-configuration&#xFF09;&#x3002;</p>
<p>&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x5728; Spring &#x9ED8;&#x8BA4;&#x529F;&#x80FD;&#x4E0A;&#x6DFB;&#x52A0;&#x4E86;&#x4EE5;&#x4E0B;&#x529F;&#x80FD;&#xFF1A;</p>
<ul>
<li>&#x5F15;&#x5165; <code>ContentNegotiatingViewResolver</code> &#x548C; <code>BeanNameViewResolver</code> bean&#x3002;</li>
<li>&#x652F;&#x6301;&#x670D;&#x52A1;&#x9759;&#x6001;&#x8D44;&#x6E90;&#xFF0C;&#x5305;&#x62EC;&#x5BF9; WebJar &#x7684;&#x652F;&#x6301;&#xFF08;<a href="#boot-features-spring-mvc-static-content">&#x89C1;&#x4E0B;&#x6587;</a>&#xFF09;&#x3002;</li>
<li>&#x81EA;&#x52A8;&#x6CE8;&#x518C; <code>Converter</code>&#x3001;<code>GenericConverter</code> &#x548C; <code>Formatter</code> bean&#x3002;</li>
<li>&#x652F;&#x6301; <code>HttpMessageConverter</code>&#xFF08;&#x89C1;<a href="#boot-features-spring-mvc-message-converters">&#x4E0B;&#x6587;</a>&#xFF09;&#x3002;</li>
<li>&#x81EA;&#x52A8;&#x6CE8;&#x518C; <code>MessageCodesResolver</code>&#xFF08;&#x89C1;<a href="#boot-features-spring-message-codes">&#x4E0B;&#x6587;</a>&#xFF09;&#x3002;</li>
<li>&#x652F;&#x6301;&#x9759;&#x6001; index.html&#x3002;</li>
<li>&#x652F;&#x6301;&#x81EA;&#x5B9A;&#x4E49; Favicon &#xFF08;&#x89C1;<a href="#boot-features-spring-mvc-favicon">&#x4E0B;&#x6587;</a>&#xFF09;&#x3002;</li>
<li>&#x81EA;&#x52A8;&#x4F7F;&#x7528; <code>ConfigurableWebBindingInitializer</code> bean&#xFF08;&#x89C1;<a href="#boot-features-spring-mvc-web-binding-initializer">&#x4E0B;&#x6587;</a>&#xFF09;&#x3002;</li>
</ul>
<p>&#x5982;&#x679C;&#x60A8;&#x60F3;&#x4FDD;&#x7559; Spring Boot MVC &#x7684;&#x529F;&#x80FD;&#xFF0C;&#x5E76;&#x4E14;&#x9700;&#x8981;&#x6DFB;&#x52A0;&#x5176;&#x4ED6; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#mvc" target="_blank">MVC &#x914D;&#x7F6E;</a>&#xFF08;interceptor&#x3001;formatter &#x548C;&#x89C6;&#x56FE;&#x63A7;&#x5236;&#x5668;&#x7B49;&#xFF09;&#xFF0C;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0;&#x81EA;&#x5DF1;&#x7684; <code>WebMvcConfigurerAdapter</code> &#x7C7B;&#x578B;&#x7684; <code>@Configuration</code> &#x7C7B;&#xFF0C;&#x4F46;<strong>&#x4E0D;&#x80FD;</strong>&#x5E26; <code>@EnableWebMvc</code> &#x6CE8;&#x89E3;&#x3002;&#x5982;&#x679C;&#x60A8;&#x60F3;&#x81EA;&#x5B9A;&#x4E49; <code>RequestMappingHandlerMapping</code>&#x3001;<code>RequestMappingHandlerAdapter</code> &#x6216;&#x8005; <code>ExceptionHandlerExceptionResolver</code> &#x5B9E;&#x4F8B;&#xFF0C;&#x53EF;&#x4EE5;&#x58F0;&#x660E;&#x4E00;&#x4E2A; <code>WebMvcRegistrationsAdapter</code> &#x5B9E;&#x4F8B;&#x6765;&#x63D0;&#x4F9B;&#x8FD9;&#x4E9B;&#x7EC4;&#x4EF6;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x60F3;&#x5B8C;&#x5168;&#x638C;&#x63A7; Spring MVC&#xFF0C;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0;&#x81EA;&#x5B9A;&#x4E49;&#x6CE8;&#x89E3;&#x4E86; <code>@EnableWebMvc</code> &#x7684; @Configuration &#x914D;&#x7F6E;&#x7C7B;&#x3002;</p>
<p><a id="boot-features-spring-mvc-message-converters"></a></p>
<h4 id="2812&#x3001;httpmessageconverters">28.1.2&#x3001;HttpMessageConverters</h4>
<p>Spring MVC &#x4F7F;&#x7528; <code>HttpMessageConverter</code> &#x63A5;&#x53E3;&#x6765;&#x8F6C;&#x6362; HTTP &#x7684;&#x8BF7;&#x6C42;&#x548C;&#x54CD;&#x5E94;&#x3002;&#x5F00;&#x7BB1;&#x5373;&#x7528;&#x529F;&#x80FD;&#x5305;&#x542B;&#x4E86;&#x5408;&#x9002;&#x7684;&#x9ED8;&#x8BA4;&#x503C;&#xFF0C;&#x6BD4;&#x5982;&#x5BF9;&#x8C61;&#x53EF;&#x4EE5;&#x81EA;&#x52A8;&#x8F6C;&#x6362;&#x4E3A; JSON&#xFF08;&#x4F7F;&#x7528; Jackson &#x5E93;&#xFF09;&#x6216;&#x8005; XML&#xFF08;&#x4F18;&#x5148;&#x4F7F;&#x7528; Jackson XML &#x6269;&#x5C55;&#xFF0C;&#x5176;&#x6B21;&#x4E3A; JAXB&#xFF09;&#x3002;&#x5B57;&#x7B26;&#x4E32;&#x9ED8;&#x8BA4;&#x4F7F;&#x7528; <code>UTF-8</code> &#x7F16;&#x7801;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x6DFB;&#x52A0;&#x6216;&#x8005;&#x81EA;&#x5B9A;&#x4E49;&#x8F6C;&#x6362;&#x5668;&#xFF08;converter&#xFF09;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; Spring Boot &#x7684; <code>HttpMessageConverters</code> &#x7C7B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span>web</span><span class="token punctuation">.</span><span class="token class-name">HttpMessageConverters</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>context<span class="token punctuation">.</span>annotation</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>http<span class="token punctuation">.</span>converter</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>

<span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyConfiguration</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">HttpMessageConverters</span> <span class="token function">customConverters</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">HttpMessageConverter</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token operator">?</span><span class="token punctuation">&gt;</span></span> additional <span class="token operator">=</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
        <span class="token class-name">HttpMessageConverter</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token operator">?</span><span class="token punctuation">&gt;</span></span> another <span class="token operator">=</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">HttpMessageConverters</span><span class="token punctuation">(</span>additional<span class="token punctuation">,</span> another<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x7684;&#x6240;&#x6709; <code>HttpMessageConverter</code> bean &#x90FD;&#x5C06;&#x88AB;&#x6DFB;&#x52A0;&#x5230;&#x8F6C;&#x6362;&#x5668;&#x5217;&#x8868;&#x4E2D;&#x3002;&#x60A8;&#x4E5F;&#x53EF;&#x4EE5;&#x7528;&#x8FD9;&#x79CD;&#x65B9;&#x5F0F;&#x6765;&#x8986;&#x76D6;&#x9ED8;&#x8BA4;&#x8F6C;&#x6362;&#x5668;&#x3002;</p>
<p><a id="boot-features-json-components"></a></p>
<h4 id="2813&#x3001;&#x81EA;&#x5B9A;&#x4E49;-json-serializer-&#x548C;-deserializer">28.1.3&#x3001;&#x81EA;&#x5B9A;&#x4E49; JSON Serializer &#x548C; Deserializer</h4>
<p>&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528; Jackson &#x5E8F;&#x5217;&#x5316;&#x548C;&#x53CD;&#x5E8F;&#x5217;&#x5316; JSON &#x6570;&#x636E;&#xFF0C;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x81EA;&#x5DF1;&#x7F16;&#x5199; <code>JsonSerializer</code> &#x548C; <code>JsonDeserializer</code> &#x7C7B;&#x3002;&#x81EA;&#x5B9A;&#x4E49;&#x5E8F;&#x5217;&#x5316;&#x5668;&#xFF08;serializer&#xFF09;&#x7684;&#x505A;&#x6CD5;&#x901A;&#x5E38;&#x662F;&#x901A;&#x8FC7;<a href="https://github.com/FasterXML/jackson-docs/wiki/JacksonHowToCustomSerializers" target="_blank">&#x4E00;&#x4E2A;&#x6A21;&#x5757;&#x6765;&#x6CE8;&#x518C; Jackson</a>&#xFF0C; &#x7136;&#x800C; Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x5907;&#x9009;&#x7684; <code>@JsonComponent</code> &#x6CE8;&#x89E3;&#xFF0C;&#x5B83;&#x53EF;&#x4EE5;&#x66F4;&#x52A0;&#x5BB9;&#x6613;&#x5730;&#x76F4;&#x63A5;&#x6CE8;&#x518C; Spring Bean&#x3002;</p>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x5728; <code>JsonSerializer</code> &#x6216;&#x8005; <code>JsonDeserializer</code> &#x5B9E;&#x73B0;&#x4E0A;&#x4F7F;&#x7528; <code>@JsonComponent</code> &#x6CE8;&#x89E3;&#x3002;&#x60A8;&#x4E5F;&#x53EF;&#x4EE5;&#x5728;&#x5C06;&#x5E8F;&#x5217;&#x5316;&#x5668;/&#x53CD;&#x5E8F;&#x5217;&#x5316;&#x5668;&#xFF08;deserializer&#xFF09;&#x4F5C;&#x4E3A;&#x5185;&#x90E8;&#x7C7B;&#x7684;&#x7C7B;&#x4E0A;&#x4F7F;&#x7528;&#x3002;&#x4F8B;&#x5982;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>io</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>fasterxml<span class="token punctuation">.</span>jackson<span class="token punctuation">.</span>core</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>fasterxml<span class="token punctuation">.</span>jackson<span class="token punctuation">.</span>databind</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>jackson</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>

<span class="token annotation punctuation">@JsonComponent</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Example</span> <span class="token punctuation">{</span>

    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">Serializer</span> <span class="token keyword">extends</span> <span class="token class-name">JsonSerializer</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">SomeObject</span><span class="token punctuation">&gt;</span></span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">Deserializer</span> <span class="token keyword">extends</span> <span class="token class-name">JsonDeserializer</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">SomeObject</span><span class="token punctuation">&gt;</span></span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><code>ApplicationContext</code> &#x4E2D;&#x6240;&#x6709;&#x7684; <code>@JsonComponent</code> bean &#x5C06;&#x88AB;&#x81EA;&#x52A8;&#x6CE8;&#x518C;&#x5230; Jackson &#x4E2D;&#xFF0C;&#x7531;&#x4E8E; <code>@JsonComponent</code> &#x4F7F;&#x7528; <code>@Component</code> &#x6CE8;&#x89E3;&#x6807;&#x8BB0;&#xFF0C;&#x56E0;&#x6B64;&#x7EC4;&#x4EF6;&#x626B;&#x63CF;&#xFF08;component-scanning&#xFF09;&#x89C4;&#x5219;&#x5C06;&#x5BF9;&#x5176;&#x751F;&#x6548;&#x3002;</p>
<p>Spring Boot &#x8FD8;&#x63D0;&#x4F9B;&#x4E86; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonObjectSerializer.java" target="_blank">JsonObjectSerializer</a> &#x548C; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jackson/JsonObjectDeserializer.java" target="_blank">JsonObjectDeserializer</a> &#x57FA;&#x7C7B;&#xFF0C;&#x5B83;&#x4EEC;&#x5728;&#x5E8F;&#x5217;&#x5316;&#x5BF9;&#x8C61;&#x65F6;&#x4E3A;&#x6807;&#x51C6;&#x7684; Jackson &#x7248;&#x672C;&#x63D0;&#x4F9B;&#x4E86;&#x6709;&#x7528;&#x7684;&#x66FF;&#x4EE3;&#x65B9;&#x6848;&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; Javadoc &#x4E2D;&#x7684; <a href="https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/api/org/springframework/boot/jackson/JsonObjectSerializer.html" target="_blank">JsonObjectSerializer</a> &#x548C; <a href="https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/api/org/springframework/boot/jackson/JsonObjectDeserializer.html" target="_blank">JsonObjectDeserializer</a>&#x3002;</p>
<p><a id="boot-features-spring-message-codes"></a></p>
<h4 id="2814&#x3001;messagecodesresolver">28.1.4&#x3001;MessageCodesResolver</h4>
<p>Spring MVC &#x6709;&#x4E00;&#x4E2A;&#x4ECE;&#x7ED1;&#x5B9A;&#x9519;&#x8BEF;&#x4E2D;&#x751F;&#x6210;&#x9519;&#x8BEF;&#x7801;&#x7684;&#x7B56;&#x7565;&#xFF0C;&#x7528;&#x4E8E;&#x6E32;&#x67D3;&#x9519;&#x8BEF;&#x4FE1;&#x606F;&#xFF1A;<code>MessageCodesResolver</code>&#x3002;&#x5982;&#x679C;&#x60A8;&#x8BBE;&#x7F6E;&#x4E86; <code>spring.mvc.message-codes-resolver.format</code> &#x5C5E;&#x6027;&#x503C;&#x4E3A; <code>PREFIX_ERROR_CODE</code> &#x6216; <code>POSTFIX_ERROR_CODE</code>&#xFF0C;Spring Boot &#x5C06;&#x4E3A;&#x4F60;&#x521B;&#x5EFA;&#x8BE5;&#x7B56;&#x7565;&#xFF08;&#x8BF7;&#x53C2;&#x9605; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/validation/DefaultMessageCodesResolver.Format.html" target="_blank">DefaultMessageCodesResolver.Format</a> &#x4E2D;&#x7684;&#x679A;&#x4E3E;&#xFF09;&#x3002;</p>
<p><a id="boot-features-spring-mvc-static-content"></a></p>
<h4 id="2815&#x3001;&#x9759;&#x6001;&#x5185;&#x5BB9;">28.1.5&#x3001;&#x9759;&#x6001;&#x5185;&#x5BB9;</h4>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Spring Boot &#x5C06;&#x5728; classpath &#x6216;&#x8005; <code>ServletContext</code> &#x6839;&#x76EE;&#x5F55;&#x4E0B;&#x4ECE;&#x540D;&#x4E3A; <code>/static</code> &#xFF08;<code>/public</code>&#x3001;<code>/resources</code> &#x6216; <code>/META-INF/resources</code>&#xFF09;&#x76EE;&#x5F55;&#x4E2D;&#x670D;&#x52A1;&#x9759;&#x6001;&#x5185;&#x5BB9;&#x3002;&#x5B83;&#x4F7F;&#x7528;&#x4E86; Spring MVC &#x7684; <code>ResourceHttpRequestHandler</code>&#xFF0C;&#x56E0;&#x6B64;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6DFB;&#x52A0;&#x81EA;&#x5DF1;&#x7684; <code>WebMvcConfigurerAdapter</code> &#x5E76;&#x91CD;&#x5199; <code>addResourceHandlers</code> &#x65B9;&#x6CD5;&#x6765;&#x4FEE;&#x6539;&#x6B64;&#x884C;&#x4E3A;&#x3002;</p>
<p>&#x5728;&#x4E00;&#x4E2A;&#x72EC;&#x7ACB;&#x7684;&#xFF08;stand-alone&#xFF09; web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#xFF0C;&#x6765;&#x81EA;&#x5BB9;&#x5668;&#x7684;&#x9ED8;&#x8BA4; servlet &#x4E5F;&#x662F;&#x88AB;&#x542F;&#x7528;&#x7684;&#xFF0C;&#x5E76;&#x5145;&#x5F53;&#x4E00;&#x4E2A;&#x56DE;&#x9000;&#x652F;&#x63F4;&#xFF0C;Spring &#x51B3;&#x5B9A;&#x4E0D;&#x5904;&#x7406; <code>ServletContext</code> &#x6839;&#x76EE;&#x5F55;&#x4E0B;&#x7684;&#x9759;&#x6001;&#x8D44;&#x6E90;&#xFF0C;&#x5BB9;&#x5668;&#x7684;&#x9ED8;&#x8BA4; servlet &#x4E5F;&#x5C06;&#x4F1A;&#x5904;&#x7406;&#x3002;&#x5927;&#x591A;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x8FD9;&#x662F;&#x4E0D;&#x4F1A;&#x53D1;&#x751F;&#x7684;&#xFF08;&#x9664;&#x975E;&#x60A8;&#x4FEE;&#x6539;&#x4E86;&#x9ED8;&#x8BA4;&#x7684; MVC &#x914D;&#x7F6E;&#xFF09;&#xFF0C;&#x56E0;&#x4E3A; Spring &#x59CB;&#x7EC8;&#x80FD;&#x901A;&#x8FC7; <code>DispatcherServlet</code> &#x6765;&#x5904;&#x7406;&#x8BF7;&#x6C42;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x8D44;&#x6E90;&#x88AB;&#x6620;&#x5C04;&#x5230; <code>/**</code>&#xFF0C;&#x4F46;&#x53EF;&#x4EE5;&#x901A;&#x8FC7; <code>spring.mvc.static-path-pattern</code> &#x5C5E;&#x6027;&#x8C03;&#x6574;&#x3002;&#x6BD4;&#x5982;&#xFF0C;&#x5C06;&#x6240;&#x6709;&#x8D44;&#x6E90;&#x91CD;&#x5B9A;&#x4F4D;&#x5230; <code>/resources/**</code>&#xFF1A;</p>
<pre class="language-"><code>spring.mvc.static-path-pattern=/resources/**
</code></pre><p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.resources.static-locations</code> &#x5C5E;&#x6027;&#x6765;&#x81EA;&#x5B9A;&#x4E49;&#x9759;&#x6001;&#x8D44;&#x6E90;&#x7684;&#x4F4D;&#x7F6E;&#xFF08;&#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x76EE;&#x5F55;&#x4F4D;&#x7F6E;&#x5217;&#x8868;&#x66FF;&#x6362;&#x9ED8;&#x8BA4;&#x503C;&#xFF09;&#x3002;&#x6839; Servlet context path <code>/</code> &#x81EA;&#x52A8;&#x4F5C;&#x4E3A;&#x4E00;&#x4E2A; location &#x6DFB;&#x52A0;&#x8FDB;&#x6765;&#x3002;</p>
<p>&#x9664;&#x4E86;&#x4E0A;&#x8FF0;&#x63D0;&#x5230;&#x7684;<strong>&#x6807;&#x51C6;</strong>&#x9759;&#x6001;&#x8D44;&#x6E90;&#x4F4D;&#x7F6E;&#x4E4B;&#x5916;&#xFF0C;&#x8FD8;&#x6709;&#x4E00;&#x79CD;&#x7279;&#x6B8A;&#x60C5;&#x51B5;&#x662F;&#x7528;&#x4E8E; <a href="https://www.webjars.org/" target="_blank">Webjar &#x5185;&#x5BB9;</a>&#x3002;&#x5982;&#x679C;&#x4EE5; Webjar &#x683C;&#x5F0F;&#x6253;&#x5305;&#xFF0C;&#x5219;&#x6240;&#x6709;&#x7B26;&#x5408; <code>/webjars/**</code> &#x7684;&#x8D44;&#x6E90;&#x90FD;&#x5C06;&#x4ECE; jar &#x6587;&#x4EF6;&#x4E2D;&#x670D;&#x52A1;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x8981;&#x5305;&#x6210; jar&#xFF0C;&#x8BF7;&#x4E0D;&#x8981;&#x4F7F;&#x7528; <code>src/main/webapp</code> &#x76EE;&#x5F55;&#x3002;&#x867D;&#x7136;&#x6B64;&#x76EE;&#x5F55;&#x662F;&#x4E00;&#x4E2A;&#x901A;&#x7528;&#x6807;&#x51C6;&#xFF0C;&#x4F46;&#x5B83;<strong>&#x53EA;</strong>&#x9002;&#x7528;&#x4E8E; war &#x6253;&#x5305;&#xFF0C;&#x5982;&#x679C;&#x751F;&#x6210;&#x7684;&#x662F;&#x4E00;&#x4E2A; jar&#xFF0C;&#x5B83;&#x5C06;&#x88AB;&#x7EDD;&#x5927;&#x591A;&#x6570;&#x7684;&#x6784;&#x5EFA;&#x5DE5;&#x5177;&#x6240;&#x5FFD;&#x7565;&#x3002;</p>
</blockquote>
<p>Spring Boot &#x8FD8;&#x652F;&#x6301; Spring MVC &#x63D0;&#x4F9B;&#x7684;&#x9AD8;&#x7EA7;&#x8D44;&#x6E90;&#x5904;&#x7406;&#x529F;&#x80FD;&#xFF0C;&#x5141;&#x8BB8;&#x4F7F;&#x7528;&#x4F8B;&#x5982;&#x9759;&#x6001;&#x8D44;&#x6E90;&#x7F13;&#x5B58;&#x6E05;&#x9664;&#xFF08;cache busting&#xFF09;&#x6216;&#x8005; Webjar &#x7248;&#x672C;&#x65E0;&#x5173; URL&#x3002;</p>
<p>&#x8981;&#x4F7F;&#x7528; Webjar &#x7248;&#x672C;&#x65E0;&#x5173; URL &#x529F;&#x80FD;&#xFF0C;&#x53EA;&#x9700;&#x8981;&#x6DFB;&#x52A0; <code>webjars-locator-core</code> &#x4F9D;&#x8D56;&#x3002;&#x7136;&#x540E;&#x58F0;&#x660E;&#x60A8;&#x7684; Webjar&#xFF0C;&#x4EE5; jQuery &#x4E3A;&#x4F8B;&#xFF0C;&#x6DFB;&#x52A0;&#x7684; <code>&quot;/webjars/jquery/dist/jquery.min.js&quot;</code> &#x5C06;&#x53D8;&#x6210; <code>&quot;/webjars/jquery/x.y.z/dist/jquery.min.js&quot;</code>&#xFF0C;&#x5176;&#x4E2D; <code>x.y.z</code> &#x662F; Webjar &#x7684;&#x7248;&#x672C;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528; JBoss&#xFF0C;&#x5219;&#x9700;&#x8981;&#x58F0;&#x660E; <code>webjars-locator-jboss-vfs</code> &#x4F9D;&#x8D56;&#xFF0C;&#x800C;&#x4E0D;&#x662F; <code>webjars-locator-core</code>&#xFF0C;&#x5426;&#x5219;&#x6240;&#x6709; Webjar &#x5C06;&#x88AB;&#x89E3;&#x6790;&#x6210; <code>404</code>&#x3002;</p>
</blockquote>
<p>&#x8981;&#x4F7F;&#x7528;&#x7F13;&#x5B58;&#x6E05;&#x9664;&#x529F;&#x80FD;&#xFF0C;&#x4EE5;&#x4E0B;&#x914D;&#x7F6E;&#x4E3A;&#x6240;&#x6709;&#x9759;&#x6001;&#x8D44;&#x6E90;&#x914D;&#x7F6E;&#x4E86;&#x4E00;&#x4E2A;&#x7F13;&#x5B58;&#x6E05;&#x9664;&#x65B9;&#x6848;&#xFF0C;&#x5B9E;&#x9645;&#x4E0A;&#x662F;&#x5728; URL &#x4E0A;&#x6DFB;&#x52A0;&#x4E86;&#x4E00;&#x4E2A;&#x5185;&#x5BB9;&#x54C8;&#x5E0C;&#xFF0C;&#x4F8B;&#x5982; <code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span></code>&#xFF1A;</p>
<pre class="language-"><code>pring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
</code></pre><p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x6A21;&#x677F;&#x4E2D;&#x7684;&#x8D44;&#x6E90;&#x94FE;&#x63A5;&#x5728;&#x8FD0;&#x884C;&#x65F6;&#x88AB;&#x91CD;&#x5199;&#xFF0C;&#x8FD9;&#x5F97;&#x76CA;&#x4E8E; <code>ResourceUrlEncodingFilter</code> &#x4E3A; Thymeleaf &#x548C; FreeMarker &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x5728;&#x4F7F;&#x7528; JSP &#x65F6;&#xFF0C;&#x60A8;&#x5E94;&#x8BE5;&#x624B;&#x52A8;&#x58F0;&#x660E;&#x6B64;&#x8FC7;&#x6EE4;&#x5668;&#x3002;&#x5176;&#x4ED6;&#x6A21;&#x677F;&#x5F15;&#x64CE;&#x73B0;&#x5728;&#x8FD8;&#x4E0D;&#x4F1A;&#x81EA;&#x52A8;&#x652F;&#x6301;&#xFF0C;&#x4F46;&#x53EF;&#x4EE5;&#x4E0E;&#x81EA;&#x5B9A;&#x4E49;&#x6A21;&#x677F;&#x5B8F;&#xFF08;macro&#xFF09;/helper &#x548C; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/web/servlet/resource/ResourceUrlProvider.html" target="_blank"><code>ResourceUrlProvider</code></a> &#x7ED3;&#x5408;&#x4F7F;&#x7528;&#x3002;</p>
</blockquote>
<p>&#x5F53;&#x4F7F;&#x7528;&#x4F8B;&#x5982; Javascript &#x6A21;&#x5757;&#x52A0;&#x8F7D;&#x5668;&#x52A8;&#x6001;&#x52A0;&#x8F7D;&#x8D44;&#x6E90;&#x65F6;&#xFF0C;&#x91CD;&#x547D;&#x540D;&#x6587;&#x4EF6;&#x662F;&#x4E0D;&#x53EF;&#x9009;&#x7684;&#x3002;&#x8FD9;&#x4E5F;&#x662F;&#x4E3A;&#x4EC0;&#x4E48;&#x652F;&#x6301;&#x5176;&#x4ED6;&#x7B56;&#x7565;&#x5E76;&#x4E14;&#x53EF;&#x4EE5;&#x7EC4;&#x5408;&#x4F7F;&#x7528;&#x7684;&#x539F;&#x56E0;&#x3002;<strong>fixed</strong>&#x7B56;&#x7565;&#x5C06;&#x5728; URL &#x4E2D;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A;&#x9759;&#x6001;&#x7248;&#x672C;&#x5B57;&#x7B26;&#x4E32;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x66F4;&#x6539;&#x6587;&#x4EF6;&#x540D;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.resources.chain.strategy.content.enabled</span><span class="token attr-value"><span class="token punctuation">=</span>true</span>
<span class="token constant">spring.resources.chain.strategy.content.paths</span><span class="token attr-value"><span class="token punctuation">=</span>/**</span>
<span class="token constant">spring.resources.chain.strategy.fixed.enabled</span><span class="token attr-value"><span class="token punctuation">=</span>true</span>
<span class="token constant">spring.resources.chain.strategy.fixed.paths</span><span class="token attr-value"><span class="token punctuation">=</span>/js/lib/</span>
<span class="token constant">spring.resources.chain.strategy.fixed.version</span><span class="token attr-value"><span class="token punctuation">=</span>v12</span>
</code></pre>
<p>&#x4F7F;&#x7528;&#x6B64;&#x914D;&#x7F6E;&#xFF0C;JavaScript &#x6A21;&#x5757;&#x5B9A;&#x4F4D;&#x5728; <code>&quot;/js/lib/&quot;</code> &#x4E0B;&#x4F7F;&#x7528;&#x56FA;&#x5B9A;&#x7248;&#x672C;&#x7B56;&#x7565;&#xFF08;<code>&quot;/v12/js/lib/mymodule.js&quot;</code>&#xFF09;&#xFF0C;&#x800C;&#x5176;&#x4ED6;&#x8D44;&#x6E90;&#x4ECD;&#x4F7F;&#x7528;&#x5185;&#x5BB9;&#x7B56;&#x7565;&#xFF08;<code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>link</span> <span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css<span class="token punctuation">&quot;</span></span><span class="token punctuation">/&gt;</span></span></code>&#xFF09;&#x3002;</p>
<p>&#x6709;&#x5173;&#x66F4;&#x591A;&#x652F;&#x6301;&#x9009;&#x9879;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ResourceProperties.java" target="_blank">ResourceProperties</a>&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x8BE5;&#x529F;&#x80FD;&#x5DF2;&#x7ECF;&#x5728;&#x4E00;&#x4E2A;&#x4E13;&#x95E8;&#x7684;<a href="https://spring.io/blog/2014/07/24/spring-framework-4-1-handling-static-web-resources" target="_blank">&#x535A;&#x5BA2;&#x6587;&#x7AE0;</a>&#x548C; Spring &#x6846;&#x67B6;&#x7684;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#mvc-config-static-resources" target="_blank">&#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x4E2D;&#x8FDB;&#x884C;&#x4E86;&#x8BE6;&#x7EC6;&#x63CF;&#x8FF0;&#x3002;</p>
</blockquote>
<p><a id="boot-features-spring-mvc-welcome-page"></a></p>
<h4 id="2816&#x3001;&#x6B22;&#x8FCE;&#x9875;&#x9762;">28.1.6&#x3001;&#x6B22;&#x8FCE;&#x9875;&#x9762;</h4>
<p>Spring Boot &#x652F;&#x6301;&#x9759;&#x6001;&#x548C;&#x6A21;&#x677F;&#x5316;&#x7684;&#x6B22;&#x8FCE;&#x9875;&#x9762;&#x3002;&#x5B83;&#x9996;&#x5148;&#x5728;&#x914D;&#x7F6E;&#x7684;&#x9759;&#x6001;&#x5185;&#x5BB9;&#x4F4D;&#x7F6E;&#x4E2D;&#x67E5;&#x627E; <code>index.html</code> &#x6587;&#x4EF6;&#x3002;&#x5982;&#x679C;&#x627E;&#x4E0D;&#x5230;&#xFF0C;&#x5219;&#x67E5;&#x627E; <code>index</code> &#x6A21;&#x677F;&#x3002;&#x5982;&#x679C;&#x627E;&#x5230;&#x5176;&#x4E2D;&#x4EFB;&#x4F55;&#x4E00;&#x4E2A;&#xFF0C;&#x5B83;&#x5C06;&#x81EA;&#x52A8;&#x7528;&#x4F5C;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x6B22;&#x8FCE;&#x9875;&#x9762;&#x3002;</p>
<p><a id="boot-features-spring-mvc-favicon"></a></p>
<h4 id="2817&#x3001;&#x81EA;&#x5B9A;&#x4E49;-favicon">28.1.7&#x3001;&#x81EA;&#x5B9A;&#x4E49; Favicon</h4>
<p>Spring Boot &#x5728;&#x914D;&#x7F6E;&#x7684;&#x9759;&#x6001;&#x5185;&#x5BB9;&#x4F4D;&#x7F6E;&#x548C;&#x6839; classpath &#x4E2D;&#x67E5;&#x627E; <code>favicon.ico</code>&#xFF08;&#x6309;&#x987A;&#x5E8F;&#xFF09;&#x3002;&#x5982;&#x679C;&#x8BE5;&#x6587;&#x4EF6;&#x5B58;&#x5728;&#xFF0C;&#x5219;&#x5C06;&#x88AB;&#x81EA;&#x52A8;&#x7528;&#x4F5C;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684; favicon&#x3002;</p>
<p><a id="boot-features-spring-mvc-pathmatch"></a></p>
<h4 id="2818&#x3001;&#x8DEF;&#x5F84;&#x5339;&#x914D;&#x4E0E;&#x5185;&#x5BB9;&#x534F;&#x5546;">28.1.8&#x3001;&#x8DEF;&#x5F84;&#x5339;&#x914D;&#x4E0E;&#x5185;&#x5BB9;&#x534F;&#x5546;</h4>
<p>Spring MVC &#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x67E5;&#x770B;&#x8BF7;&#x6C42;&#x8DEF;&#x5F84;&#x5E76;&#x5C06;&#x5176;&#x4E0E;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x5B9A;&#x4E49;&#x7684;&#x6620;&#x5C04;&#x76F8;&#x5339;&#x914D;&#xFF0C;&#x5C06;&#x4F20;&#x5165;&#x7684; HTTP &#x8BF7;&#x6C42;&#x6620;&#x5C04;&#x5230;&#x5904;&#x7406;&#x7A0B;&#x5E8F;&#xFF08;&#x4F8B;&#x5982; Controller &#x65B9;&#x6CD5;&#x4E0A;&#x7684; <code>@GetMapping</code> &#x6CE8;&#x89E3;&#xFF09;&#x3002;</p>
<p>Spring Boot &#x9ED8;&#x8BA4;&#x9009;&#x62E9;&#x7981;&#x7528;&#x540E;&#x7F00;&#x6A21;&#x5F0F;&#x5339;&#x914D;&#xFF0C;&#x8FD9;&#x610F;&#x5473;&#x7740;&#x50CF; <code>&quot;GET /projects/spring-boot.json&quot;</code> &#x8FD9;&#x6837;&#x7684;&#x8BF7;&#x6C42;&#x5C06;&#x4E0D;&#x4F1A;&#x4E0E; <code>@GetMapping(&quot;/projects/spring-boot&quot;)</code> &#x6620;&#x5C04;&#x5339;&#x914D;&#x3002;&#x8FD9;&#x88AB;&#x89C6;&#x4E3A;&#x662F; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#mvc-ann-requestmapping-suffix-pattern-match" target="_blank">Spring MVC &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x6700;&#x4F73;&#x5B9E;&#x8DF5;</a>&#x3002;&#x6B64;&#x529F;&#x80FD;&#x5728;&#x8FC7;&#x53BB;&#x5BF9;&#x4E8E; HTTP &#x5BA2;&#x6237;&#x7AEF;&#x6CA1;&#x6709;&#x53D1;&#x9001;&#x6B63;&#x786E;&#x7684; <strong>Accept</strong> &#x8BF7;&#x6C42;&#x5934;&#x7684;&#x60C5;&#x51B5;&#x8FD8;&#x662F;&#x5F88;&#x6709;&#x7528;&#x7684;&#xFF0C;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x786E;&#x4FDD;&#x5C06;&#x6B63;&#x786E;&#x7684;&#x5185;&#x5BB9;&#x7C7B;&#x578B;&#x53D1;&#x9001;&#x7ED9;&#x5BA2;&#x6237;&#x7AEF;&#x3002;&#x5982;&#x4ECA;&#xFF0C;&#x5185;&#x5BB9;&#x534F;&#x5546;&#xFF08;Content Negotiation&#xFF09;&#x66F4;&#x52A0;&#x53EF;&#x9760;&#x3002;</p>
<p>&#x8FD8;&#x6709;&#x5176;&#x4ED6;&#x65B9;&#x6CD5;&#x53EF;&#x4EE5;&#x5904;&#x7406; HTTP &#x5BA2;&#x6237;&#x7AEF;&#x53D1;&#x9001;&#x4E0D;&#x4E00;&#x81F4; <strong>Accept</strong> &#x8BF7;&#x6C42;&#x5934;&#x95EE;&#x9898;&#x3002;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x67E5;&#x8BE2;&#x53C2;&#x6570;&#x6765;&#x786E;&#x4FDD;&#x50CF; <code>&quot;GET /projects/spring-boot?format=json&quot;</code> &#x8FD9;&#x6837;&#x7684;&#x8BF7;&#x6C42;&#x6620;&#x5C04;&#x5230; <code>@GetMapping(&quot;/projects/spring-boot&quot;)</code>&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x4F7F;&#x7528;&#x540E;&#x7F00;&#x5339;&#x914D;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.mvc.contentnegotiation.favor-parameter</span><span class="token attr-value"><span class="token punctuation">=</span>true</span>

<span class="token comment"># We can change the parameter name, which is &quot;format&quot; by default:</span>
<span class="token comment"># spring.mvc.contentnegotiation.parameter-name=myparam</span>

<span class="token comment"># We can also register additional file extensions/media types with:</span>
<span class="token constant">spring.mvc.contentnegotiation.media-types.markdown</span><span class="token attr-value"><span class="token punctuation">=</span>text/markdown</span>
</code></pre>
<p>&#x5982;&#x679C;&#x60A8;&#x4E86;&#x89E3;&#x76F8;&#x5173;&#x6CE8;&#x610F;&#x4E8B;&#x9879;&#x5E76;&#x4ECD;&#x5E0C;&#x671B;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4F7F;&#x7528;&#x540E;&#x7F00;&#x6A21;&#x5F0F;&#x5339;&#x914D;&#xFF0C;&#x5219;&#x9700;&#x8981;&#x4EE5;&#x4E0B;&#x914D;&#x7F6E;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.mvc.contentnegotiation.favor-path-extension</span><span class="token attr-value"><span class="token punctuation">=</span>true</span>
<span class="token constant">spring.mvc.pathmatch.use-suffix-pattern</span><span class="token attr-value"><span class="token punctuation">=</span>true</span>
</code></pre>
<p>&#x6216;&#x8005;&#xFF0C;&#x4E0D;&#x6253;&#x5F00;&#x6240;&#x6709;&#x540E;&#x7F00;&#x6A21;&#x5F0F;&#xFF0C;&#x4EC5;&#x6253;&#x5F00;&#x652F;&#x6301;&#x5DF2;&#x6CE8;&#x518C;&#x7684;&#x540E;&#x7F00;&#x6A21;&#x5F0F;&#x66F4;&#x52A0;&#x5B89;&#x5168;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.mvc.contentnegotiation.favor-path-extension</span><span class="token attr-value"><span class="token punctuation">=</span>true</span>
<span class="token constant">spring.mvc.pathmatch.use-registered-suffix-pattern</span><span class="token attr-value"><span class="token punctuation">=</span>true</span>

<span class="token comment"># You can also register additional file extensions/media types with:</span>
<span class="token comment"># spring.mvc.contentnegotiation.media-types.adoc=text/asciidoc</span>
</code></pre>
<p><a id="boot-features-spring-mvc-web-binding-initializer"></a></p>
<h4 id="2819&#x3001;configurablewebbindinginitializer">28.1.9&#x3001;ConfigurableWebBindingInitializer</h4>
<p>Spring MVC &#x4F7F;&#x7528;&#x4E00;&#x4E2A; <code>WebBindingInitializer</code> &#x4E3A;&#x7279;&#x5B9A;&#x7684;&#x8BF7;&#x6C42;&#x521D;&#x59CB;&#x5316; <code>WebDataBinder</code>&#x3002;&#x5982;&#x679C;&#x60A8;&#x521B;&#x5EFA;&#x4E86;&#x81EA;&#x5DF1;&#x7684; <code>ConfigurableWebBindingInitializer</code> <code>@Bean</code>&#xFF0C;Spring Boot &#x5C06;&#x81EA;&#x52A8;&#x914D;&#x7F6E; Spring MVC &#x4F7F;&#x7528;&#x5B83;&#x3002;</p>
<p><a id="boot-features-spring-mvc-template-engines"></a></p>
<h4 id="28110&#x3001;&#x6A21;&#x677F;&#x5F15;&#x64CE;">28.1.10&#x3001;&#x6A21;&#x677F;&#x5F15;&#x64CE;</h4>
<p>&#x9664;&#x4E86; REST web &#x670D;&#x52A1;&#x4E4B;&#x5916;&#xFF0C;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; Spring MVC &#x6765;&#x670D;&#x52A1;&#x52A8;&#x6001; HTML &#x5185;&#x5BB9;&#x3002;Spring MVC &#x652F;&#x6301;&#x591A;&#x79CD;&#x6A21;&#x677F;&#x6280;&#x672F;&#xFF0C;&#x5305;&#x62EC; Thymeleaf&#x3001;FreeMarker &#x548C; JSP&#x3002;&#x5F53;&#x7136;&#xFF0C;&#x8BB8;&#x591A;&#x5176;&#x4ED6;&#x6A21;&#x677F;&#x5F15;&#x64CE;&#x4E5F;&#x6709;&#x81EA;&#x5DF1;&#x7684; Spring MVC &#x96C6;&#x6210;&#x3002;</p>
<p>Spring Boot &#x5305;&#x542B;&#x4E86;&#x4EE5;&#x4E0B;&#x7684;&#x6A21;&#x677F;&#x5F15;&#x64CE;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x652F;&#x6301;&#xFF1A;</p>
<ul>
<li><a href="https://freemarker.apache.org/docs/" target="_blank">FreeMarker</a></li>
<li><a href="http://docs.groovy-lang.org/docs/next/html/documentation/template-engines.html#_the_markuptemplateengine" target="_blank">Groovy</a></li>
<li><a href="http://www.thymeleaf.org/" target="_blank">Thymeleaf</a></li>
<li><a href="https://mustache.github.io/" target="_blank">Mustache</a></li>
</ul>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x53EF;&#x4EE5;&#xFF0C;&#x8BF7;&#x5C3D;&#x91CF;&#x907F;&#x514D;&#x4F7F;&#x7528; JSP&#xFF0C;&#x5F53;&#x4F7F;&#x7528;&#x4E86;&#x5185;&#x5D4C; servlet &#x5BB9;&#x5668;&#xFF0C;&#x4F1A;&#x6709;&#x51E0;&#x4E2A;<a href="#boot-features-jsp-limitations">&#x5DF2;&#x77E5;&#x9650;&#x5236;</a>&#x3002;</p>
</blockquote>
<p>&#x5F53;&#x60A8;&#x4F7F;&#x7528;&#x8FD9;&#x4E9B;&#x6A21;&#x677F;&#x5F15;&#x64CE;&#x7684;&#x5176;&#x4E2D;&#x4E00;&#x4E2A;&#x5E76;&#x9644;&#x5E26;&#x4E86;&#x9ED8;&#x8BA4;&#x914D;&#x7F6E;&#x65F6;&#xFF0C;&#x60A8;&#x7684;&#x6A21;&#x677F;&#x5C06;&#x4ECE; <code>src/main/resources/templates</code> &#x81EA;&#x52A8;&#x83B7;&#x53D6;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>IntelliJ IDEA &#x6839;&#x636E;&#x60A8;&#x8FD0;&#x884C;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x65B9;&#x5F0F;&#x6765;&#x5BF9; classpath &#x8FDB;&#x884C;&#x4E0D;&#x540C;&#x7684;&#x6392;&#x5E8F;&#x3002;&#x5728; IDE &#x4E2D;&#x901A;&#x8FC7; main &#x65B9;&#x6CD5;&#x6765;&#x8FD0;&#x884C;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5C06;&#x5BFC;&#x81F4;&#x4E0E;&#x4F7F;&#x7528; Maven &#x6216; Gradle &#x6216;&#x6765;&#x4EE5; jar &#x5305;&#x65B9;&#x5F0F;&#x5F15;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x6392;&#x5E8F;&#x6709;&#x6240;&#x4E0D;&#x540C;&#xFF0C;&#x53EF;&#x80FD;&#x4F1A;&#x5BFC;&#x81F4; Spring Boot &#x627E;&#x4E0D;&#x5230; classpath &#x4E2D;&#x7684;&#x6A21;&#x677F;&#x3002;&#x5982;&#x679C;&#x60A8;&#x78B0;&#x5230;&#x5230;&#x6B64;&#x95EE;&#x9898;&#xFF0C;&#x53EF;&#x4EE5;&#x91CD;&#x65B0;&#x6392;&#x5E8F; IDE &#x7684; classpath &#x6765;&#x653E;&#x7F6E;&#x6A21;&#x5757;&#x7684; classes &#x548C; resources &#x5230;&#x9996;&#x4F4D;&#x3002;&#x6216;&#x8005;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x914D;&#x7F6E;&#x6A21;&#x677F;&#x524D;&#x7F00;&#x6765;&#x641C;&#x7D22; classpath &#x4E2D;&#x7684;&#x6BCF;&#x4E00;&#x4E2A; <code>templates</code> &#x76EE;&#x5F55;&#xFF0C;&#x6BD4;&#x5982;&#xFF1A;<code>classpath*:/templates/</code>&#x3002; </p>
</blockquote>
<p><a id="boot-features-error-handling"></a></p>
<h4 id="28111&#x3001;&#x9519;&#x8BEF;&#x5904;&#x7406;">28.1.11&#x3001;&#x9519;&#x8BEF;&#x5904;&#x7406;</h4>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x4F7F;&#x7528;&#x4E86;&#x6BD4;&#x8F83;&#x5408;&#x7406;&#x7684;&#x65B9;&#x5F0F;&#x6765;&#x5904;&#x7406;&#x6240;&#x6709;&#x9519;&#x8BEF;&#x7684; <code>/error</code> &#x6620;&#x5C04;&#xFF0C;&#x5176;&#x5728; servlet &#x5BB9;&#x5668;&#x4E2D;&#x6CE8;&#x518C;&#x4E86;&#x4E00;&#x4E2A;<strong>&#x5168;&#x5C40;</strong>&#x9519;&#x8BEF;&#x9875;&#x9762;&#x3002;&#x5BF9;&#x4E8E;&#x673A;&#x5668;&#x5BA2;&#x6237;&#x7AEF;&#x800C;&#x8A00;&#xFF0C;&#x5B83;&#x5C06;&#x4EA7;&#x751F;&#x4E00;&#x4E2A;&#x5305;&#x542B;&#x9519;&#x8BEF;&#x3001;HTTP &#x72B6;&#x6001;&#x548C;&#x5F02;&#x5E38;&#x6D88;&#x606F;&#x7684; JSON &#x54CD;&#x5E94;&#x3002;&#x5BF9;&#x4E8E;&#x6D4F;&#x89C8;&#x5668;&#x5BA2;&#x6237;&#x7AEF;&#x800C;&#x8A00;&#xFF0C;&#x5C06;&#x4EE5; HTML &#x683C;&#x5F0F;&#x5448;&#x73B0;&#x76F8;&#x540C;&#x6570;&#x636E;&#x7684; <strong>whitelabel</strong> &#x9519;&#x8BEF;&#x89C6;&#x56FE;&#xFF08;&#x53EF;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A;&#x89E3;&#x6790;&#x5230; <code>error</code> &#x7684; <code>View</code> &#x8FDB;&#x884C;&#x81EA;&#x5B9A;&#x4E49;&#xFF09;&#x3002;&#x8981;&#x5B8C;&#x5168;&#x66FF;&#x6362;&#x9ED8;&#x8BA4;&#x884C;&#x4E3A;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5B9E;&#x73B0; <code>ErrorController</code> &#x5E76;&#x6CE8;&#x518C;&#x8BE5;&#x7C7B;&#x578B;&#x7684; bean&#xFF0C;&#x6216;&#x8005;&#x7B80;&#x5355;&#x5730;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A;&#x7C7B;&#x578B;&#x4E3A; <code>ErrorAttributes</code> &#x7684; bean &#x6765;&#x66FF;&#x6362;&#x5185;&#x5BB9;&#xFF0C;&#x4F46;&#x7EE7;&#x7EED;&#x4F7F;&#x7528;&#x73B0;&#x7528;&#x673A;&#x5236;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p><code>BasicErrorController</code> &#x53EF;&#x4EE5;&#x4F5C;&#x4E3A;&#x81EA;&#x5B9A;&#x4E49; <code>ErrorController</code> &#x7684;&#x57FA;&#x7C7B;&#xFF0C;&#x8FD9;&#x975E;&#x5E38;&#x6709;&#x7528;&#xFF0C;&#x5C24;&#x5176;&#x662F;&#x5728;&#x60A8;&#x60F3;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A;&#x65B0;&#x7684;&#x5185;&#x5BB9;&#x7C7B;&#x578B;&#xFF08;&#x9ED8;&#x8BA4;&#x4E13;&#x95E8;&#x5904;&#x7406; <code>text/html</code>&#xFF0C;&#x5E76;&#x4E3A;&#x5176;&#x4ED6;&#x5185;&#x5BB9;&#x63D0;&#x4F9B;&#x540E;&#x5907;&#xFF09;&#x5904;&#x7406;&#x5668;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#x3002;&#x8981;&#x505A;&#x5230;&#x8FD9;&#x70B9;&#xFF0C;&#x60A8;&#x53EA;&#x9700;&#x8981;&#x7EE7;&#x627F; <code>BasicErrorController</code> &#x5E76;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A;&#x5E26;&#x6709; <code>produces</code> &#x5C5E;&#x6027;&#x7684; <code>@RequestMapping</code> &#x6CE8;&#x89E3;&#x7684;&#x516C;&#x5171;&#x65B9;&#x6CD5;&#xFF0C;&#x4E4B;&#x540E;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x65B0;&#x7C7B;&#x578B;&#x7684; bean&#x3002;</p>
</blockquote>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;&#x5E26;&#x6709; <code>@ControllerAdvice</code> &#x6CE8;&#x89E3;&#x7684;&#x7C7B;&#x6765;&#x81EA;&#x5B9A;&#x4E49;&#x4E3A;&#x7279;&#x5B9A;&#x63A7;&#x5236;&#x5668;&#x6216;&#x5F02;&#x5E38;&#x7C7B;&#x578B;&#x8FD4;&#x56DE;&#x7684; JSON &#x6587;&#x6863;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@ControllerAdvice</span><span class="token punctuation">(</span>basePackageClasses <span class="token operator">=</span> <span class="token class-name">AcmeController</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">AcmeControllerAdvice</span> <span class="token keyword">extends</span> <span class="token class-name">ResponseEntityExceptionHandler</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@ExceptionHandler</span><span class="token punctuation">(</span><span class="token class-name">YourException</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
    <span class="token annotation punctuation">@ResponseBody</span>
    <span class="token class-name">ResponseEntity</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token operator">?</span><span class="token punctuation">&gt;</span></span> <span class="token function">handleControllerException</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">Throwable</span> ex<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">HttpStatus</span> status <span class="token operator">=</span> <span class="token function">getStatus</span><span class="token punctuation">(</span>request<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">ResponseEntity</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">CustomErrorType</span><span class="token punctuation">(</span>status<span class="token punctuation">.</span><span class="token function">value</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> ex<span class="token punctuation">.</span><span class="token function">getMessage</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> status<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">private</span> <span class="token class-name">HttpStatus</span> <span class="token function">getStatus</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">Integer</span> statusCode <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token class-name">Integer</span><span class="token punctuation">)</span> request<span class="token punctuation">.</span><span class="token function">getAttribute</span><span class="token punctuation">(</span><span class="token string">&quot;javax.servlet.error.status_code&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>statusCode <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">return</span> <span class="token class-name">HttpStatus</span><span class="token punctuation">.</span>INTERNAL_SERVER_ERROR<span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> <span class="token class-name">HttpStatus</span><span class="token punctuation">.</span><span class="token function">valueOf</span><span class="token punctuation">(</span>statusCode<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x4EE5;&#x4E0A;&#x793A;&#x4F8B;&#x4E2D;&#xFF0C;&#x5982;&#x679C;&#x540C;&#x5305;&#x4E0B;&#x5B9A;&#x4E49;&#x7684;&#x63A7;&#x5236;&#x5668; <code>AcmeController</code> &#x629B;&#x51FA;&#x4E86; <code>YourException</code>&#xFF0C;&#x5219;&#x5C06;&#x4F7F;&#x7528; <code>CustomerErrorType</code> &#x7C7B;&#x578B;&#x7684; POJO &#x6765;&#x4EE3;&#x66FF; <code>ErrorAttributes</code> &#x505A; JSON &#x5448;&#x73B0;&#x3002;</p>
<p><a id="boot-features-error-handling-custom-error-pages"></a></p>
<h5 id="281111&#x3001;&#x81EA;&#x5B9A;&#x4E49;&#x9519;&#x8BEF;&#x9875;&#x9762;">28.1.11.1&#x3001;&#x81EA;&#x5B9A;&#x4E49;&#x9519;&#x8BEF;&#x9875;&#x9762;</h5>
<p>&#x5982;&#x679C;&#x60A8;&#x60F3;&#x5728;&#x81EA;&#x5B9A;&#x4E49;&#x7684; HTML &#x9519;&#x8BEF;&#x9875;&#x9762;&#x4E0A;&#x663E;&#x793A;&#x7ED9;&#x5B9A;&#x7684;&#x72B6;&#x6001;&#x7801;&#xFF0C;&#x8BF7;&#x5C06;&#x6587;&#x4EF6;&#x6DFB;&#x52A0;&#x5230; <code>/error</code> &#x6587;&#x4EF6;&#x5939;&#x4E2D;&#x3002;&#x9519;&#x8BEF;&#x9875;&#x9762;&#x53EF;&#x4EE5;&#x662F;&#x9759;&#x6001; HTML&#xFF08;&#x6DFB;&#x52A0;&#x5728;&#x4EFB;&#x610F;&#x9759;&#x6001;&#x8D44;&#x6E90;&#x6587;&#x4EF6;&#x5939;&#x4E0B;) &#x6216;&#x8005;&#x4F7F;&#x7528;&#x6A21;&#x677F;&#x6784;&#x5EFA;&#x3002;&#x6587;&#x4EF6;&#x7684;&#x540D;&#x79F0;&#x5E94;&#x8BE5;&#x662F;&#x786E;&#x5207;&#x7684;&#x72B6;&#x6001;&#x7801;&#x6216;&#x8005;&#x4E00;&#x4E2A;&#x5E8F;&#x5217;&#x63A9;&#x7801;&#x3002;</p>
<p>&#x4F8B;&#x5982;&#xFF0C;&#x8981;&#x5C06; <code>404</code> &#x6620;&#x5C04;&#x5230;&#x4E00;&#x4E2A;&#x9759;&#x6001; HTML &#x6587;&#x4EF6;&#xFF0C;&#x6587;&#x4EF6;&#x5939;&#x7ED3;&#x6784;&#x53EF;&#x4EE5;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre class="language-"><code>src/
 +- main/
     +- java/
     |   + <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>source</span> <span class="token attr-name">code</span><span class="token punctuation">&gt;</span></span>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>other</span> <span class="token attr-name">public</span> <span class="token attr-name">assets</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>&#x4F7F;&#x7528; FreeMarker &#x6A21;&#x677F;&#x6765;&#x6620;&#x5C04;&#x6240;&#x6709; <code>5xx</code> &#x9519;&#x8BEF;&#xFF0C;&#x6587;&#x4EF6;&#x5939;&#x7684;&#x7ED3;&#x6784;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre class="language-"><code>src/
 +- main/
     +- java/
     |   + <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>source</span> <span class="token attr-name">code</span><span class="token punctuation">&gt;</span></span>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.ftl
             +- <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>other</span> <span class="token attr-name">templates</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>&#x5BF9;&#x4E8E;&#x66F4;&#x590D;&#x6742;&#x7684;&#x6620;&#x5C04;&#xFF0C;&#x60A8;&#x8FD8;&#x901A;&#x8FC7;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0;&#x5B9E;&#x73B0;&#x4E86; <code>ErrorViewResolver</code> &#x63A5;&#x53E3;&#x7684; bean &#x6765;&#x5904;&#x7406;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyErrorViewResolver</span> <span class="token keyword">implements</span> <span class="token class-name">ErrorViewResolver</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token class-name">ModelAndView</span> <span class="token function">resolveErrorView</span><span class="token punctuation">(</span><span class="token class-name">HttpServletRequest</span> request<span class="token punctuation">,</span>
            <span class="token class-name">HttpStatus</span> status<span class="token punctuation">,</span> <span class="token class-name">Map</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">String</span><span class="token punctuation">,</span> <span class="token class-name">Object</span><span class="token punctuation">&gt;</span></span> model<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// Use the request or status to optionally return a ModelAndView</span>
        <span class="token keyword">return</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x5E38;&#x89C4;&#x7684; Spring MVC &#x529F;&#x80FD;&#xFF0C;&#x6BD4;&#x5982; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#mvc-exceptionhandlers" target="_blank"><code>@ExceptionHandler</code> &#x65B9;&#x6CD5;</a>&#x548C; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#mvc-ann-controller-advice" target="_blank">@ControllerAdvice</a><code>&#x3002;&#x4E4B;&#x540E;&#xFF0C;ErrorController</code> &#x5C06;&#x80FD;&#x63A5;&#x6536;&#x4EFB;&#x4F55;&#x672A;&#x5904;&#x7406;&#x7684;&#x5F02;&#x5E38;&#x3002;</p>
<p><a id="boot-features-error-handling-mapping-error-pages-without-mvc"></a></p>
<h5 id="281112&#x3001;&#x6620;&#x5C04;&#x5230;-spring-mvc-&#x4E4B;&#x5916;&#x7684;&#x9519;&#x8BEF;&#x9875;&#x9762;">28.1.11.2&#x3001;&#x6620;&#x5C04;&#x5230; Spring MVC &#x4E4B;&#x5916;&#x7684;&#x9519;&#x8BEF;&#x9875;&#x9762;</h5>
<p>&#x5BF9;&#x4E8E;&#x4E0D;&#x4F7F;&#x7528; Spring MVC &#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>ErrorPageRegistrar</code> &#x63A5;&#x53E3;&#x6765;&#x76F4;&#x63A5;&#x6CE8;&#x518C; <code>ErrorPages</code>&#x3002;&#x62BD;&#x8C61;&#x90E8;&#x5206;&#x76F4;&#x63A5;&#x4E0E;&#x5E95;&#x5C42;&#x7684;&#x5185;&#x5D4C; servlet &#x5BB9;&#x5668;&#x4E00;&#x8D77;&#x5DE5;&#x4F5C;&#xFF0C;&#x5373;&#x4F7F;&#x60A8;&#x6CA1;&#x6709; Spring MVC <code>DispatcherServlet</code> &#x4E5F;&#x80FD;&#x4F7F;&#x7528;&#x3002;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">ErrorPageRegistrar</span> <span class="token function">errorPageRegistrar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">MyErrorPageRegistrar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token comment">// ...</span>

<span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">MyErrorPageRegistrar</span> <span class="token keyword">implements</span> <span class="token class-name">ErrorPageRegistrar</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">registerErrorPages</span><span class="token punctuation">(</span><span class="token class-name">ErrorPageRegistry</span> registry<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        registry<span class="token punctuation">.</span><span class="token function">addErrorPages</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">ErrorPage</span><span class="token punctuation">(</span><span class="token class-name">HttpStatus</span><span class="token punctuation">.</span>BAD_REQUEST<span class="token punctuation">,</span> <span class="token string">&quot;/400&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x6CE8;&#x518C;&#x4E86;&#x4E00;&#x4E2A; <code>ErrorPage</code>&#xFF0C;&#x5B83;&#x7684;&#x8DEF;&#x5F84;&#x6700;&#x7EC8;&#x7531;&#x4E00;&#x4E2A; <code>Filter</code>&#xFF08;&#x4F8B;&#x5982;&#xFF0C;&#x50CF;&#x4E00;&#x4E9B;&#x975E; Spring web &#x6846;&#x67B6;&#x4E00;&#x6837;&#xFF0C;&#x6BD4;&#x5982; Jersey &#x548C; Wicket&#xFF09;&#x5904;&#x7406;&#xFF0C;&#x5219;&#x5FC5;&#x987B;&#x5C06; Filter &#x663E;&#x5F0F;&#x6CE8;&#x518C;&#x4E3A;&#x4E00;&#x4E2A; <code>ERROR</code> dispatcher&#xFF0C;&#x5982;&#x4E0B;&#x793A;&#x4F8B;&#xFF1A;</p>
</blockquote>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">FilterRegistrationBean</span> <span class="token function">myFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token class-name">FilterRegistrationBean</span> registration <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FilterRegistrationBean</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    registration<span class="token punctuation">.</span><span class="token function">setFilter</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">MyFilter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    registration<span class="token punctuation">.</span><span class="token function">setDispatcherTypes</span><span class="token punctuation">(</span><span class="token class-name">EnumSet</span><span class="token punctuation">.</span><span class="token function">allOf</span><span class="token punctuation">(</span><span class="token class-name">DispatcherType</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> registration<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>&#x8BF7;&#x6CE8;&#x610F;&#xFF0C;&#x9ED8;&#x8BA4;&#x7684; <code>FilterRegistrationBean</code> &#x4E0D;&#x5305;&#x542B; <code>ERROR</code> &#x8C03;&#x5EA6;&#x5668;&#xFF08;dispatcher&#xFF09;&#x7C7B;&#x578B;&#x3002;</p>
<p><strong>&#x5F53;&#x5FC3;</strong>&#xFF1A;&#x5F53;&#x90E8;&#x7F72;&#x5230; servlet &#x5BB9;&#x5668;&#x65F6;&#xFF0C;Spring Boot &#x4F7F;&#x7528;&#x5176;&#x9519;&#x8BEF;&#x9875;&#x9762;&#x8FC7;&#x6EE4;&#x5668;&#x4F1A;&#x5C06;&#x6709;&#x9519;&#x8BEF;&#x72B6;&#x6001;&#x7684;&#x8BF7;&#x6C42;&#x8F6C;&#x53D1;&#x5230;&#x76F8;&#x5E94;&#x7684;&#x9519;&#x8BEF;&#x9875;&#x9762;&#x3002;&#x5982;&#x679C;&#x5C1A;&#x672A;&#x63D0;&#x4EA4;&#x54CD;&#x5E94;&#xFF0C;&#x5219;&#x53EA;&#x80FD;&#x5C06;&#x8BF7;&#x6C42;&#x8F6C;&#x53D1;&#x5230;&#x6B63;&#x786E;&#x7684;&#x9519;&#x8BEF;&#x9875;&#x9762;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;WebSphere Application Server 8.0 &#x53CA;&#x66F4;&#x9AD8;&#x7248;&#x672C;&#x5728;&#x6210;&#x529F;&#x5B8C;&#x6210; servlet &#x7684; service &#x65B9;&#x6CD5;&#x540E;&#x63D0;&#x4EA4;&#x54CD;&#x5E94;&#x3002;&#x60A8;&#x5E94;&#x8BE5;&#x5C06; <code>com.ibm.ws.webcontainer.invokeFlushAfterService</code> &#x8BBE;&#x7F6E;&#x4E3A; <code>false</code> &#x6765;&#x7981;&#x7528;&#x6B64;&#x884C;&#x4E3A;&#x3002;</p>
<p><a id="boot-features-spring-hateoas"></a></p>
<h4 id="28112&#x3001;spring-hateoas">28.1.12&#x3001;Spring HATEOAS</h4>
<p>&#x5982;&#x679C;&#x60A8;&#x60F3;&#x5F00;&#x53D1;&#x4E00;&#x4E2A;&#x4F7F;&#x7528;&#x8D85;&#x5A92;&#x4F53;&#xFF08;hypermedia&#xFF09;&#x7684; RESTful API&#xFF0C;Spring Boot &#x63D0;&#x4F9B;&#x7684; Spring HATEOAS &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x5728;&#x5927;&#x591A;&#x6570;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x90FD;&#x5DE5;&#x4F5C;&#x5F97;&#x975E;&#x5E38;&#x597D;&#x3002;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x53D6;&#x4EE3;&#x4E86; <code>@EnableHypermediaSupport</code> &#x7684;&#x9700;&#x8981;&#xFF0C;&#x5E76;&#x6CE8;&#x518C;&#x4E86;&#x4E00;&#x4E9B; bean&#xFF0C;&#x4EE5;&#x4FBF;&#x80FD;&#x8F7B;&#x677E;&#x6784;&#x5EFA;&#x57FA;&#x4E8E;&#x8D85;&#x5A92;&#x4F53;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;&#x5176;&#x5305;&#x62EC;&#x4E86;&#x4E00;&#x4E2A; <code>LinkDiscoverers</code> &#xFF08;&#x7528;&#x4E8E;&#x5BA2;&#x6237;&#x7AEF;&#x652F;&#x6301;&#xFF09;&#x548C;&#x4E00;&#x4E2A;&#x7528;&#x4E8E;&#x914D;&#x7F6E;&#x5C06;&#x54CD;&#x5E94;&#x6B63;&#x786E;&#x5448;&#x73B0;&#x7684; <code>ObjectMapper</code>&#x3002;<code>ObjectMapper</code> &#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>spring.jackson.*</code> &#x5C5E;&#x6027;&#x6216;&#x8005; <code>Jackson2ObjectMapperBuilder</code> bean &#xFF08;&#x5982;&#x679C;&#x5B58;&#x5728;&#xFF09;&#x81EA;&#x5B9A;&#x4E49;&#x3002;</p>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@EnableHypermediaSupport</code> &#x6765;&#x63A7;&#x5236; Spring HATEOAS &#x7684;&#x914D;&#x7F6E;&#x3002;&#x8BF7;&#x6CE8;&#x610F;&#xFF0C;&#x8FD9;&#x4F7F;&#x5F97;&#x4E0A;&#x8FF0;&#x7684;&#x81EA;&#x5B9A;&#x4E49; ObjectMapper &#x88AB;&#x7981;&#x7528;&#x3002;</p>
<p><a id="boot-features-cors"></a></p>
<h4 id="28113&#x3001;cors-&#x652F;&#x6301;">28.1.13&#x3001;CORS &#x652F;&#x6301;</h4>
<p><a href="https://en.wikipedia.org/wiki/Cross-origin_resource_sharing" target="_blank">&#x8DE8;&#x57DF;&#x8D44;&#x6E90;&#x5171;&#x4EAB;</a>&#xFF08;Cross-origin resource sharing&#xFF0C;CORS&#xFF09;&#x662F;<a href="https://caniuse.com/#feat=cors" target="_blank">&#x5927;&#x591A;&#x6570;&#x6D4F;&#x89C8;&#x5668;</a>&#x5B9E;&#x73B0;&#x7684;&#x4E00;&#x4E2A; <a href="https://www.w3.org/TR/cors/" target="_blank">W3C &#x89C4;&#x8303;</a>&#xFF0C;&#x5176;&#x53EF;&#x5141;&#x8BB8;&#x60A8;&#x4EE5;&#x7075;&#x6D3B;&#x7684;&#x65B9;&#x5F0F;&#x6307;&#x5B9A;&#x4F55;&#x79CD;&#x8DE8;&#x57DF;&#x8BF7;&#x6C42;&#x53EF;&#x4EE5;&#x88AB;&#x6388;&#x6743;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x4F7F;&#x7528;&#x4E00;&#x4E9B;&#x4E0D;&#x592A;&#x5B89;&#x5168;&#x548C;&#x4E0D;&#x592A;&#x5F3A;&#x5927;&#x7684;&#x65B9;&#x5F0F;&#xFF08;&#x6BD4;&#x5982; IFRAME &#x6216;&#x8005; JSONP&#xFF09;&#x3002;</p>
<p>Spring MVC &#x4ECE; 4.2 &#x7248;&#x672C;&#x8D77;&#x5F00;&#x59CB;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#cors" target="_blank">&#x652F;&#x6301; CORS</a>&#x3002;&#x60A8;&#x53EF;&#x5728; Spring Boot &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x4F7F;&#x7528; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#controller-method-cors-configuration" target="_blank"><code>@CrossOrigin</code></a> &#x6CE8;&#x89E3;&#x914D;&#x7F6E;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#controller-method-cors-configuration" target="_blank">&#x63A7;&#x5236;&#x5668;&#x65B9;&#x6CD5;&#x542F;&#x7528; CORS</a>&#x3002;&#x8FD8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6CE8;&#x518C;&#x4E00;&#x4E2A; WebMvcConfigurer bean &#x5E76;&#x81EA;&#x5B9A;&#x4E49; <code>addCorsMappings(CorsRegistry)</code> &#x65B9;&#x6CD5;&#x6765;&#x5B9A;&#x4E49;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#global-cors-configuration" target="_blank">&#x5168;&#x5C40; CORS &#x914D;&#x7F6E;</a>&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyConfiguration</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">WebMvcConfigurer</span> <span class="token function">corsConfigurer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">WebMvcConfigurer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token annotation punctuation">@Override</span>
            <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">addCorsMappings</span><span class="token punctuation">(</span><span class="token class-name">CorsRegistry</span> registry<span class="token punctuation">)</span> <span class="token punctuation">{</span>
                registry<span class="token punctuation">.</span><span class="token function">addMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/api/**&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-webflux"></a></p>
<h3 id="282&#x3001;spring-webflux-&#x6846;&#x67B6;">28.2&#x3001;Spring WebFlux &#x6846;&#x67B6;</h3>
<p>Spring WebFlux &#x662F; Spring Framework 5.0 &#x4E2D;&#x65B0;&#x5F15;&#x5165;&#x7684;&#x4E00;&#x4E2A;&#x54CD;&#x5E94;&#x5F0F; Web &#x6846;&#x67B6;&#x3002;&#x4E0E; Spring MVC &#x4E0D;&#x540C;&#xFF0C;&#x5B83;&#x4E0D;&#x9700;&#x8981; Servlet API&#xFF0C;&#x5B8C;&#x5168;&#x5F02;&#x6B65;&#x4E14;&#x65E0;&#x963B;&#x585E;&#xFF0C;&#x5E76;&#x901A;&#x8FC7; <a href="http://www.reactive-streams.org/" target="_blank">Reactor &#x9879;&#x76EE;</a>&#x5B9E;&#x73B0;<a href="http://www.reactive-streams.org/" target="_blank">&#x54CD;&#x5E94;&#x5F0F;&#x6D41;&#xFF08;Reactive Streams&#xFF09;</a>&#x89C4;&#x8303;&#x3002;</p>
<p>Spring WebFlux &#x6709;&#x4E24;&#x4E2A;&#x7248;&#x672C;&#xFF1A;&#x51FD;&#x6570;&#x5F0F;&#x548C;&#x57FA;&#x4E8E;&#x6CE8;&#x89E3;&#x3002;&#x57FA;&#x4E8E;&#x6CE8;&#x89E3;&#x7684;&#x65B9;&#x5F0F;&#x975E;&#x5E38;&#x63A5;&#x8FD1; Spring MVC &#x6A21;&#x578B;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@RestController</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/users&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyRestController</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/{user}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">Mono</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">User</span><span class="token punctuation">&gt;</span></span> <span class="token function">getUser</span><span class="token punctuation">(</span><span class="token annotation punctuation">@PathVariable</span> <span class="token class-name">Long</span> user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@GetMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/{user}/customers&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">Flux</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Customer</span><span class="token punctuation">&gt;</span></span> <span class="token function">getUserCustomers</span><span class="token punctuation">(</span><span class="token annotation punctuation">@PathVariable</span> <span class="token class-name">Long</span> user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@DeleteMapping</span><span class="token punctuation">(</span><span class="token string">&quot;/{user}&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">Mono</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">User</span><span class="token punctuation">&gt;</span></span> <span class="token function">deleteUser</span><span class="token punctuation">(</span><span class="token annotation punctuation">@PathVariable</span> <span class="token class-name">Long</span> user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>WebFlux.fn</strong> &#x4E3A;&#x51FD;&#x6570;&#x5F0F;&#x8C03;&#x7528;&#x65B9;&#x5F0F;&#xFF0C;&#x5B83;&#x5C06;&#x8DEF;&#x7531;&#x914D;&#x7F6E;&#x4E0E;&#x8BF7;&#x6C42;&#x5904;&#x7406;&#x5206;&#x5F00;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">RoutingConfiguration</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">RouterFunction</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">ServerResponse</span><span class="token punctuation">&gt;</span></span> <span class="token function">monoRouterFunction</span><span class="token punctuation">(</span><span class="token class-name">UserHandler</span> userHandler<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token function">route</span><span class="token punctuation">(</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/{user}&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">and</span><span class="token punctuation">(</span><span class="token function">accept</span><span class="token punctuation">(</span>APPLICATION_JSON<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> userHandler<span class="token operator">::</span><span class="token function">getUser</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">andRoute</span><span class="token punctuation">(</span><span class="token function">GET</span><span class="token punctuation">(</span><span class="token string">&quot;/{user}/customers&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">and</span><span class="token punctuation">(</span><span class="token function">accept</span><span class="token punctuation">(</span>APPLICATION_JSON<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> userHandler<span class="token operator">::</span><span class="token function">getUserCustomers</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">andRoute</span><span class="token punctuation">(</span><span class="token function">DELETE</span><span class="token punctuation">(</span><span class="token string">&quot;/{user}&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">and</span><span class="token punctuation">(</span><span class="token function">accept</span><span class="token punctuation">(</span>APPLICATION_JSON<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> userHandler<span class="token operator">::</span><span class="token function">deleteUser</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserHandler</span> <span class="token punctuation">{</span>

    <span class="token keyword">public</span> <span class="token class-name">Mono</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">ServerResponse</span><span class="token punctuation">&gt;</span></span> <span class="token function">getUser</span><span class="token punctuation">(</span><span class="token class-name">ServerRequest</span> request<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">Mono</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">ServerResponse</span><span class="token punctuation">&gt;</span></span> <span class="token function">getUserCustomers</span><span class="token punctuation">(</span><span class="token class-name">ServerRequest</span> request<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">Mono</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">ServerResponse</span><span class="token punctuation">&gt;</span></span> <span class="token function">deleteUser</span><span class="token punctuation">(</span><span class="token class-name">ServerRequest</span> request<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<p>WebFlux &#x662F; Spring Framework &#x7684;&#x4E00;&#x90E8;&#x5206;&#xFF0C;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#x53EF;&#x67E5;&#x770B;&#x5176;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web-reactive.html#webflux-fn" target="_blank">&#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x6839;&#x636E;&#x9700;&#x8981;&#x5B9A;&#x4E49;&#x5C3D;&#x53EF;&#x80FD;&#x591A;&#x7684; <code>RouterFunction</code> bean &#x6765;&#x6A21;&#x5757;&#x5316;&#x8DEF;&#x7531;&#x5B9A;&#x4E49;&#x3002;&#x5982;&#x679C;&#x9700;&#x8981;&#x8BBE;&#x5B9A;&#x4F18;&#x5148;&#x7EA7;&#xFF0C;Bean &#x53EF;&#x4EE5;&#x6307;&#x5B9A;&#x987A;&#x5E8F;&#x3002;</p>
</blockquote>
<p>&#x9996;&#x5148;&#xFF0C;&#x5C06; <code>spring-boot-starter-webflux</code> &#x6A21;&#x5757;&#x6DFB;&#x52A0;&#x5230;&#x60A8;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x540C;&#x65F6;&#x6DFB;&#x52A0; <code>spring-boot-starter-web</code> &#x548C; <code>spring-boot-starter-webflux</code> &#x6A21;&#x5757;&#x4F1A;&#x5BFC;&#x81F4;Spring Boot &#x81EA;&#x52A8;&#x914D;&#x7F6E; Spring MVC&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x4F7F;&#x7528; WebFlux&#x3002;&#x8FD9;&#x6837;&#x505A;&#x7684;&#x539F;&#x56E0;&#x662F;&#x56E0;&#x4E3A;&#x8BB8;&#x591A; Spring &#x5F00;&#x53D1;&#x4EBA;&#x5458;&#x5C06; <code>spring-boot-starter-webflux</code> &#x6DFB;&#x52A0;&#x5230;&#x4ED6;&#x4EEC;&#x7684; Spring MVC &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x53EA;&#x662F;&#x4E3A;&#x4E86;&#x4F7F;&#x7528;&#x54CD;&#x5E94;&#x5F0F; <code>WebClient</code>&#x3002; &#x60A8;&#x4ECD;&#x7136;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>SpringApplication.setWebApplicationType(WebApplicationType.REACTIVE)</code> &#x6765;&#x5F3A;&#x5236;&#x6267;&#x884C;&#x60A8;&#x9009;&#x62E9;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7C7B;&#x578B;&#x3002;</p>
</blockquote>
<p><a id="boot-features-webflux-auto-configuration"></a></p>
<h4 id="2821&#x3001;spring-webflux-&#x81EA;&#x52A8;&#x914D;&#x7F6E;">28.2.1&#x3001;Spring WebFlux &#x81EA;&#x52A8;&#x914D;&#x7F6E;</h4>
<p>Spring Boot &#x4E3A; Spring WebFlux &#x63D0;&#x4F9B;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x9002;&#x7528;&#x4E8E;&#x5927;&#x591A;&#x6570;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;</p>
<p>&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x5728; Spring &#x7684;&#x9ED8;&#x8BA4;&#x57FA;&#x7840;&#x4E0A;&#x6DFB;&#x52A0;&#x4E86;&#x4EE5;&#x4E0B;&#x529F;&#x80FD;&#xFF1A;</p>
<ul>
<li>&#x4E3A; <code>HttpMessageReader</code> &#x548C; <code>HttpMessageWriter</code> &#x5B9E;&#x4F8B;&#x914D;&#x7F6E;&#x7F16;&#x89E3;&#x7801;&#x5668;&#xFF08;<a href="#boot-features-webflux-httpcodecs">&#x7A0D;&#x540E;&#x5C06;&#x4ECB;&#x7ECD;</a>&#xFF09;&#x3002;</li>
<li>&#x652F;&#x6301;&#x63D0;&#x4F9B;&#x9759;&#x6001;&#x8D44;&#x6E90;&#xFF0C;&#x5305;&#x62EC;&#x5BF9; WebJars &#x7684;&#x652F;&#x6301;&#xFF08;<a href="https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#boot-features-spring-mvc-static-content" target="_blank">&#x540E;&#x9762;&#x5C06;&#x4ECB;&#x7ECD;</a>&#xFF09;&#x3002;</li>
</ul>
<p>&#x5982;&#x679C;&#x4F60;&#x8981;&#x4FDD;&#x7559; Spring Boot WebFlux &#x529F;&#x80FD;&#x5E76;&#x4E14;&#x60F3;&#x8981;&#x6DFB;&#x52A0;&#x5176;&#x4ED6; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web.html#web-reactive" target="_blank">WebFlux &#x914D;&#x7F6E;</a>&#xFF0C;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0;&#x81EA;&#x5DF1;&#x7684; <code>@Configuration</code> &#x7C7B;&#xFF0C;&#x7C7B;&#x578B;&#x4E3A; <code>WebFluxConfigurer</code>&#xFF0C;&#x4F46;&#x4E0D;&#x5305;&#x542B; <code>@EnableWebFlux</code>&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x60F3;&#x5B8C;&#x5168;&#x63A7;&#x5236; Spring WebFlux&#xFF0C;&#x53EF;&#x4EE5;&#x5C06; <code>@EnableWebFlux</code> &#x6CE8;&#x89E3;&#x5230;&#x81EA;&#x5DF1;&#x7684; @Configuration&#x3002;</p>
<p><a id="boot-features-webflux-httpcodecs"></a></p>
<h4 id="2822&#x3001;&#x4F7F;&#x7528;-httpmessagereader-&#x548C;-httpmessagewriter-&#x4F5C;&#x4E3A;-http-&#x7F16;&#x89E3;&#x7801;&#x5668;">28.2.2&#x3001;&#x4F7F;&#x7528; HttpMessageReader &#x548C; HttpMessageWriter &#x4F5C;&#x4E3A; HTTP &#x7F16;&#x89E3;&#x7801;&#x5668;</h4>
<p>Spring WebFlux &#x4F7F;&#x7528; <code>HttpMessageReader</code> &#x548C; <code>HttpMessageWriter</code> &#x63A5;&#x53E3;&#x6765;&#x8F6C;&#x6362; HTTP &#x7684;&#x8BF7;&#x6C42;&#x548C;&#x54CD;&#x5E94;&#x3002;&#x5B83;&#x4EEC;&#x901A;&#x8FC7;&#x68C0;&#x6D4B; classpath &#x4E2D;&#x53EF;&#x7528;&#x7684;&#x7C7B;&#x5E93;&#xFF0C;&#x914D;&#x7F6E;&#x4E86; <code>CodecConfigurer</code> &#x751F;&#x6210;&#x5408;&#x9002;&#x7684;&#x9ED8;&#x8BA4;&#x503C;&#x3002;</p>
<p>Spring Boot &#x901A;&#x8FC7;&#x4F7F;&#x7528; <code>CodecCustomizer</code> &#x5B9E;&#x4F8B;&#x52A0;&#x5F3A;&#x5B9A;&#x5236;&#x3002;&#x4F8B;&#x5982;&#xFF0C;<code>spring.jackson.*</code> &#x914D;&#x7F6E; key &#x5E94;&#x7528;&#x4E8E; Jackson &#x7F16;&#x89E3;&#x7801;&#x5668;&#x3002;</p>
<p>&#x5982;&#x679C;&#x9700;&#x8981;&#x6DFB;&#x52A0;&#x6216;&#x81EA;&#x5B9A;&#x4E49;&#x7F16;&#x89E3;&#x7801;&#x5668;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x81EA;&#x5B9A;&#x4E49;&#x7684; <code>CodecCustomizer</code> &#x7EC4;&#x4EF6;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>web<span class="token punctuation">.</span>codec</span><span class="token punctuation">.</span><span class="token class-name">CodecCustomizer</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyConfiguration</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">CodecCustomizer</span> <span class="token function">myCodecCustomizer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> codecConfigurer <span class="token operator">-&gt;</span> <span class="token punctuation">{</span>
            <span class="token comment">// ...</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x5229;&#x7528; <a href="#boot-features-json-components">Boot &#x7684;&#x81EA;&#x5B9A;&#x4E49; JSON &#x5E8F;&#x5217;&#x5316;&#x5668;&#x548C;&#x53CD;&#x5E8F;&#x5217;&#x5316;&#x5668;</a>&#x3002;</p>
<p><a id="boot-features-webflux-static-content"></a></p>
<h4 id="2823&#x3001;&#x9759;&#x6001;&#x5185;&#x5BB9;">28.2.3&#x3001;&#x9759;&#x6001;&#x5185;&#x5BB9;</h4>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Spring Boot &#x5C06;&#x5728; classpath &#x6216;&#x8005; <code>ServletContext</code> &#x6839;&#x76EE;&#x5F55;&#x4E0B;&#x4ECE;&#x540D;&#x4E3A; <code>/static</code> &#xFF08;<code>/public</code>&#x3001;<code>/resources</code> &#x6216; <code>/META-INF/resources</code>&#xFF09;&#x76EE;&#x5F55;&#x4E2D;&#x670D;&#x52A1;&#x9759;&#x6001;&#x5185;&#x5BB9;&#x3002;&#x5B83;&#x4F7F;&#x7528;&#x4E86; Spring WebFlux &#x7684; <code>ResourceWebHandler</code>&#xFF0C;&#x56E0;&#x6B64;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6DFB;&#x52A0;&#x81EA;&#x5DF1;&#x7684; <code>WebFluxConfigurer</code> &#x5E76;&#x91CD;&#x5199; <code>addResourceHandlers</code> &#x65B9;&#x6CD5;&#x6765;&#x4FEE;&#x6539;&#x6B64;&#x884C;&#x4E3A;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x8D44;&#x6E90;&#x88AB;&#x6620;&#x5C04;&#x5230; <code>/**</code>&#xFF0C;&#x4F46;&#x53EF;&#x4EE5;&#x901A;&#x8FC7; <code>spring.webflux.static-path-pattern</code> &#x5C5E;&#x6027;&#x8C03;&#x6574;&#x3002;&#x6BD4;&#x5982;&#xFF0C;&#x5C06;&#x6240;&#x6709;&#x8D44;&#x6E90;&#x91CD;&#x5B9A;&#x4F4D;&#x5230; <code>/resources/**</code>&#xFF1A;</p>
<pre class="language-"><code>spring.webflux.static-path-pattern=/resources/**
</code></pre><p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.resources.static-locations</code> &#x5C5E;&#x6027;&#x6765;&#x81EA;&#x5B9A;&#x4E49;&#x9759;&#x6001;&#x8D44;&#x6E90;&#x7684;&#x4F4D;&#x7F6E;&#xFF08;&#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x76EE;&#x5F55;&#x4F4D;&#x7F6E;&#x5217;&#x8868;&#x66FF;&#x6362;&#x9ED8;&#x8BA4;&#x503C;&#xFF09;&#xFF0C;&#x5982;&#x679C;&#x8FD9;&#x6837;&#x505A;&#xFF0C;&#x9ED8;&#x8BA4;&#x7684;&#x6B22;&#x8FCE;&#x9875;&#x9762;&#x68C0;&#x6D4B;&#x4F1A;&#x5207;&#x6362;&#x5230;&#x60A8;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x4F4D;&#x7F6E;&#x3002;&#x56E0;&#x6B64;&#xFF0C;&#x5982;&#x679C;&#x542F;&#x52A8;&#x65F6;&#x6709;&#x4EFB;&#x4F55;&#x5176;&#x4E2D;&#x4E00;&#x4E2A;&#x4F4D;&#x7F6E;&#x5B58;&#x5728; <code>index.html</code>&#xFF0C;&#x90A3;&#x4E48;&#x5B83;&#x5C06;&#x662F;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x4E3B;&#x9875;&#x3002;</p>
<p>&#x9664;&#x4E86;&#x4E0A;&#x8FF0;&#x63D0;&#x5230;&#x7684;<strong>&#x6807;&#x51C6;</strong>&#x9759;&#x6001;&#x8D44;&#x6E90;&#x4F4D;&#x7F6E;&#x4E4B;&#x5916;&#xFF0C;&#x8FD8;&#x6709;&#x4E00;&#x79CD;&#x7279;&#x6B8A;&#x60C5;&#x51B5;&#x662F;&#x7528;&#x4E8E; <a href="https://www.webjars.org/" target="_blank">Webjar &#x5185;&#x5BB9;</a>&#x3002;&#x5982;&#x679C;&#x4EE5; Webjar &#x683C;&#x5F0F;&#x6253;&#x5305;&#xFF0C;&#x5219;&#x6240;&#x6709;&#x7B26;&#x5408; <code>/webjars/**</code> &#x7684;&#x8D44;&#x6E90;&#x90FD;&#x5C06;&#x4ECE; jar &#x6587;&#x4EF6;&#x4E2D;&#x670D;&#x52A1;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>Spring WebFlux &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5E76;&#x4E0D;&#x4E25;&#x683C;&#x4F9D;&#x8D56;&#x4E8E; Servlet API&#xFF0C;&#x56E0;&#x6B64;&#x5B83;&#x4EEC;&#x4E0D;&#x80FD;&#x4F5C;&#x4E3A; war &#x6587;&#x4EF6;&#x90E8;&#x7F72;&#xFF0C;&#x4E5F;&#x4E0D;&#x80FD;&#x4F7F;&#x7528; <code>src/main/webapp</code> &#x76EE;&#x5F55;&#x3002;</p>
</blockquote>
<p><a id="boot-features-webflux-template-engines"></a></p>
<h4 id="2824&#x3001;&#x6A21;&#x677F;&#x5F15;&#x64CE;">28.2.4&#x3001;&#x6A21;&#x677F;&#x5F15;&#x64CE;</h4>
<p>&#x9664;&#x4E86; REST web &#x670D;&#x52A1;&#x4E4B;&#x5916;&#xFF0C;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; Spring WebFlux &#x6765;&#x670D;&#x52A1;&#x52A8;&#x6001; HTML &#x5185;&#x5BB9;&#x3002;Spring WebFlux &#x652F;&#x6301;&#x591A;&#x79CD;&#x6A21;&#x677F;&#x6280;&#x672F;&#xFF0C;&#x5305;&#x62EC; Thymeleaf&#x3001;FreeMarker &#x548C; Mustache&#x3002;</p>
<p>Spring Boot &#x5305;&#x542B;&#x4E86;&#x4EE5;&#x4E0B;&#x7684;&#x6A21;&#x677F;&#x5F15;&#x64CE;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x652F;&#x6301;&#xFF1A;</p>
<ul>
<li><a href="https://freemarker.apache.org/docs/" target="_blank">FreeMarker</a></li>
<li><a href="http://www.thymeleaf.org/" target="_blank">Thymeleaf</a></li>
<li><a href="https://mustache.github.io/" target="_blank">Mustache</a></li>
</ul>
<p>&#x5F53;&#x60A8;&#x4F7F;&#x7528;&#x8FD9;&#x4E9B;&#x6A21;&#x677F;&#x5F15;&#x64CE;&#x7684;&#x5176;&#x4E2D;&#x4E00;&#x4E2A;&#x5E76;&#x9644;&#x5E26;&#x4E86;&#x9ED8;&#x8BA4;&#x914D;&#x7F6E;&#x65F6;&#xFF0C;&#x60A8;&#x7684;&#x6A21;&#x677F;&#x5C06;&#x4ECE; <code>src/main/resources/templates</code> &#x81EA;&#x52A8;&#x83B7;&#x53D6;&#x3002;</p>
<p><a id="boot-features-webflux-error-handling"></a></p>
<h4 id="2825&#x3001;&#x9519;&#x8BEF;&#x5904;&#x7406;">28.2.5&#x3001;&#x9519;&#x8BEF;&#x5904;&#x7406;</h4>
<p>Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A; <code>WebExceptionHandler</code>&#xFF0C;&#x5B83;&#x4EE5;&#x5408;&#x7406;&#x7684;&#x65B9;&#x5F0F;&#x5904;&#x7406;&#x6240;&#x6709;&#x9519;&#x8BEF;&#x3002;&#x5B83;&#x5728;&#x5904;&#x7406;&#x987A;&#x5E8F;&#x4E2D;&#x7684;&#x4F4D;&#x7F6E;&#x7D27;&#x63A5;&#x5728; WebFlux &#x63D0;&#x4F9B;&#x7684;&#x5904;&#x7406;&#x7A0B;&#x5E8F;&#x4E4B;&#x524D;&#xFF0C;&#x8FD9;&#x4E9B;&#x5904;&#x7406;&#x5668;&#x6392;&#x5E8F;&#x662F;&#x6700;&#x540E;&#x7684;&#x3002;&#x5BF9;&#x4E8E;&#x673A;&#x5668;&#x5BA2;&#x6237;&#x7AEF;&#xFF0C;&#x5B83;&#x4F1A;&#x751F;&#x6210;&#x4E00;&#x4E2A; JSON &#x54CD;&#x5E94;&#xFF0C;&#x5176;&#x4E2D;&#x5305;&#x542B;&#x9519;&#x8BEF;&#x8BE6;&#x60C5;&#x3001;HTTP &#x72B6;&#x6001;&#x548C;&#x5F02;&#x5E38;&#x6D88;&#x606F;&#x3002;&#x5BF9;&#x4E8E;&#x6D4F;&#x89C8;&#x5668;&#x5BA2;&#x6237;&#x7AEF;&#xFF0C;&#x6709;&#x4E00;&#x4E2A; <strong>whitelabel</strong> &#x9519;&#x8BEF;&#x5904;&#x7406;&#x7A0B;&#x5E8F;&#xFF0C;&#x5B83;&#x4EE5; HTML &#x683C;&#x5F0F;&#x5448;&#x73B0;&#x540C;&#x6837;&#x7684;&#x6570;&#x636E;&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x63D0;&#x4F9B;&#x81EA;&#x5DF1;&#x7684; HTML &#x6A21;&#x677F;&#x6765;&#x663E;&#x793A;&#x9519;&#x8BEF;&#xFF08;<a href="#boot-features-webflux-error-handling-custom-error-pages">&#x8BF7;&#x53C2;&#x9605;&#x4E0B;&#x4E00;&#x8282;</a>&#xFF09;&#x3002;</p>
<p>&#x81EA;&#x5B9A;&#x4E49;&#x6B64;&#x529F;&#x80FD;&#x7684;&#x7B2C;&#x4E00;&#x6B65;&#x901A;&#x5E38;&#x4F1A;&#x6CBF;&#x7528;&#x73B0;&#x6709;&#x673A;&#x5236;&#xFF0C;&#x4F46;&#x66FF;&#x6362;&#x6216;&#x6269;&#x5145;&#x4E86;&#x9519;&#x8BEF;&#x5185;&#x5BB9;&#x3002;&#x4E3A;&#x6B64;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0; <code>ErrorAttributes</code> &#x7C7B;&#x578B;&#x7684; bean&#x3002;</p>
<p>&#x60F3;&#x8981;&#x66F4;&#x6539;&#x9519;&#x8BEF;&#x5904;&#x7406;&#x884C;&#x4E3A;&#xFF0C;&#x53EF;&#x4EE5;&#x5B9E;&#x73B0; <code>ErrorWebExceptionHandler</code> &#x5E76;&#x6CE8;&#x518C;&#x8BE5;&#x7C7B;&#x578B;&#x7684; bean&#x3002;&#x56E0;&#x4E3A; <code>WebExceptionHandler</code> &#x662F;&#x4E00;&#x4E2A;&#x975E;&#x5E38;&#x5E95;&#x5C42;&#x7684;&#x5F02;&#x5E38;&#x5904;&#x7406;&#x5668;&#xFF0C;&#x6240;&#x4EE5; Spring Boot &#x8FD8;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x65B9;&#x4FBF;&#x7684; <code>AbstractErrorWebExceptionHandler</code> &#x6765;&#x8BA9;&#x4F60;&#x4EE5; WebFlux &#x7684;&#x65B9;&#x5F0F;&#x5904;&#x7406;&#x9519;&#x8BEF;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">CustomErrorWebExceptionHandler</span> <span class="token keyword">extends</span> <span class="token class-name">AbstractErrorWebExceptionHandler</span> <span class="token punctuation">{</span>

    <span class="token comment">// Define constructor here</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> <span class="token class-name">RouterFunction</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">ServerResponse</span><span class="token punctuation">&gt;</span></span> <span class="token function">getRoutingFunction</span><span class="token punctuation">(</span><span class="token class-name">ErrorAttributes</span> errorAttributes<span class="token punctuation">)</span> <span class="token punctuation">{</span>

        <span class="token keyword">return</span> <span class="token class-name">RouterFunctions</span>
                <span class="token punctuation">.</span><span class="token function">route</span><span class="token punctuation">(</span>aPredicate<span class="token punctuation">,</span> aHandler<span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">andRoute</span><span class="token punctuation">(</span>anotherPredicate<span class="token punctuation">,</span> anotherHandler<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x8981;&#x83B7;&#x5F97;&#x66F4;&#x5B8C;&#x6574;&#x7684;&#x529F;&#x80FD;&#xFF0C;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x7EE7;&#x627F; <code>DefaultErrorWebExceptionHandler</code> &#x5E76;&#x8986;&#x76D6;&#x76F8;&#x5173;&#x65B9;&#x6CD5;&#x3002;</p>
<p><a id="boot-features-webflux-error-handling-custom-error-pages"></a></p>
<h5 id="28251&#x3001;&#x81EA;&#x5B9A;&#x4E49;&#x9519;&#x8BEF;&#x9875;&#x9762;">28.2.5.1&#x3001;&#x81EA;&#x5B9A;&#x4E49;&#x9519;&#x8BEF;&#x9875;&#x9762;</h5>
<p>&#x5982;&#x679C;&#x60A8;&#x60F3;&#x5728;&#x81EA;&#x5B9A;&#x4E49;&#x7684; HTML &#x9519;&#x8BEF;&#x9875;&#x9762;&#x4E0A;&#x663E;&#x793A;&#x7ED9;&#x5B9A;&#x7684;&#x72B6;&#x6001;&#x7801;&#xFF0C;&#x8BF7;&#x5C06;&#x6587;&#x4EF6;&#x6DFB;&#x52A0;&#x5230; <code>/error</code> &#x6587;&#x4EF6;&#x5939;&#x4E2D;&#x3002;&#x9519;&#x8BEF;&#x9875;&#x9762;&#x53EF;&#x4EE5;&#x662F;&#x9759;&#x6001; HTML&#xFF08;&#x6DFB;&#x52A0;&#x5728;&#x4EFB;&#x610F;&#x9759;&#x6001;&#x8D44;&#x6E90;&#x6587;&#x4EF6;&#x5939;&#x4E0B;) &#x6216;&#x8005;&#x4F7F;&#x7528;&#x6A21;&#x677F;&#x6784;&#x5EFA;&#x3002;&#x6587;&#x4EF6;&#x7684;&#x540D;&#x79F0;&#x5E94;&#x8BE5;&#x662F;&#x786E;&#x5207;&#x7684;&#x72B6;&#x6001;&#x7801;&#x6216;&#x8005;&#x4E00;&#x4E2A;&#x5E8F;&#x5217;&#x63A9;&#x7801;&#x3002;</p>
<p>&#x4F8B;&#x5982;&#xFF0C;&#x8981;&#x5C06; <code>404</code> &#x6620;&#x5C04;&#x5230;&#x4E00;&#x4E2A;&#x9759;&#x6001; HTML &#x6587;&#x4EF6;&#xFF0C;&#x6587;&#x4EF6;&#x5939;&#x7ED3;&#x6784;&#x53EF;&#x4EE5;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre class="language-"><code>src/
 +- main/
     +- java/
     |   + <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>source</span> <span class="token attr-name">code</span><span class="token punctuation">&gt;</span></span>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>other</span> <span class="token attr-name">public</span> <span class="token attr-name">assets</span><span class="token punctuation">&gt;</span></span>
</code></pre><p>&#x4F7F;&#x7528; Mustache &#x6A21;&#x677F;&#x6765;&#x6620;&#x5C04;&#x6240;&#x6709; <code>5xx</code> &#x9519;&#x8BEF;&#xFF0C;&#x6587;&#x4EF6;&#x5939;&#x7684;&#x7ED3;&#x6784;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre class="language-"><code>src/
 +- main/
     +- java/
     |   + <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>source</span> <span class="token attr-name">code</span><span class="token punctuation">&gt;</span></span>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.mustache
             +- <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>other</span> <span class="token attr-name">templates</span><span class="token punctuation">&gt;</span></span>
</code></pre><p><a id="boot-features-webflux-web-filters"></a></p>
<h4 id="2826&#x3001;web-&#x8FC7;&#x6EE4;&#x5668;">28.2.6&#x3001;Web &#x8FC7;&#x6EE4;&#x5668;</h4>
<p>Spring WebFlux &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A; <code>WebFilter</code> &#x63A5;&#x53E3;&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5B9E;&#x73B0;&#x8BE5;&#x63A5;&#x53E3;&#x6765;&#x8FC7;&#x6EE4; HTTP &#x8BF7;&#x6C42;/&#x54CD;&#x5E94;&#x6D88;&#x606F;&#x4EA4;&#x6362;&#x3002;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x627E;&#x5230;&#x7684; WebFilter bean &#x5C06;&#x81EA;&#x52A8;&#x7528;&#x4E8E;&#x8FC7;&#x6EE4;&#x6BCF;&#x4E2A;&#x6D88;&#x606F;&#x4EA4;&#x6362;&#x3002;</p>
<p>&#x5982;&#x679C;&#x8FC7;&#x6EE4;&#x5668;&#x7684;&#x6267;&#x884C;&#x987A;&#x5E8F;&#x5F88;&#x91CD;&#x8981;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5B9E;&#x73B0; <code>Ordered</code> &#x63A5;&#x53E3;&#x6216;&#x4F7F;&#x7528; <code>@Order</code> &#x6CE8;&#x89E3;&#x6765;&#x6307;&#x5B9A;&#x987A;&#x5E8F;&#x3002;Spring Boot &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x53EF;&#x80FD;&#x4E3A;&#x60A8;&#x914D;&#x7F6E;&#x4E86;&#x51E0;&#x4E2A; Web &#x8FC7;&#x6EE4;&#x5668;&#x3002;&#x6267;&#x884C;&#x6B64;&#x64CD;&#x4F5C;&#x65F6;&#xFF0C;&#x5C06;&#x4F7F;&#x7528;&#x4E0B;&#x8868;&#x4E2D;&#x7684;&#x987A;&#x5E8F;&#xFF1A;</p>
<table>
<thead>
<tr>
<th>Web &#x8FC7;&#x6EE4;&#x5668;</th>
<th>&#x987A;&#x5E8F;</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>MetricsWebFilter</code></td>
<td><code>Ordered.HIGHEST_PRECEDENCE + 1</code></td>
</tr>
<tr>
<td><code>WebFilterChainProxy</code>&#xFF08;Spring Security&#xFF09;</td>
<td><code>-100</code></td>
</tr>
<tr>
<td><code>HttpTraceWebFilter</code></td>
<td><code>Ordered.LOWEST_PRECEDENCE - 10</code></td>
</tr>
</tbody>
</table>
<p><a id="boot-features-jersey"></a></p>
<h3 id="283&#x3001;jax-rs-&#x4E0E;-jersey">28.3&#x3001;JAX-RS &#x4E0E; Jersey</h3>
<p>&#x5982;&#x679C;&#x60A8;&#x559C;&#x6B22; JAX-RS &#x7F16;&#x7A0B;&#x6A21;&#x578B;&#x7684; REST &#x7AEF;&#x70B9;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x5B9E;&#x73B0;&#x6765;&#x66FF;&#x4EE3; Spring MVC&#x3002;<a href="https://jersey.github.io/" target="_blank">Jersey</a> &#x548C; <a href="https://cxf.apache.org/" target="_blank">Apache CXF</a> &#x90FD;&#x80FD;&#x5F00;&#x7BB1;&#x5373;&#x7528;&#x3002;CXF &#x8981;&#x6C42;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x4EE5; <code>@Bean</code> &#x7684;&#x65B9;&#x5F0F;&#x5C06;&#x5B83;&#x6CE8;&#x518C;&#x4E3A;&#x4E00;&#x4E2A; <code>Servlet</code> &#x6216;&#x8005; <code>Filter</code>&#x3002;Jersey &#x6709;&#x90E8;&#x5206;&#x539F;&#x751F; Spring &#x652F;&#x6301;&#xFF0C;&#x6240;&#x4EE5;&#x6211;&#x4EEC;&#x4E5F;&#x5728; starter &#x4E2D;&#x63D0;&#x4F9B;&#x4E86;&#x4E0E; Spring Boot &#x6574;&#x5408;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x652F;&#x6301;&#x3002;</p>
<p>&#x8981;&#x4F7F;&#x7528; Jersey&#xFF0C;&#x53EA;&#x9700;&#x8981;&#x5C06; <code>spring-boot-starter-jersey</code> &#x4F5C;&#x4E3A;&#x4F9D;&#x8D56;&#x5F15;&#x5165;&#xFF0C;&#x7136;&#x540E;&#x60A8;&#x9700;&#x8981;&#x4E00;&#x4E2A; <code>ResourceConfig</code> &#x7C7B;&#x578B;&#x7684; <code>@Bean</code>&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728;&#x5176;&#x4E2D;&#x6CE8;&#x518C;&#x6240;&#x6709;&#x7AEF;&#x70B9;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JerseyConfig</span> <span class="token keyword">extends</span> <span class="token class-name">ResourceConfig</span> <span class="token punctuation">{</span>

    <span class="token keyword">public</span> <span class="token class-name">JerseyConfig</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token function">register</span><span class="token punctuation">(</span><span class="token class-name">Endpoint</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x8B66;&#x544A;</strong></p>
<blockquote>
<p>Jersey &#x5BF9;&#x4E8E;&#x626B;&#x63CF;&#x53EF;&#x6267;&#x884C;&#x5F52;&#x6863;&#x6587;&#x4EF6;&#x7684;&#x652F;&#x6301;&#x662F;&#x76F8;&#x5F53;&#x6709;&#x9650;&#x7684;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5B83;&#x65E0;&#x6CD5;&#x626B;&#x63CF;&#x4E00;&#x4E2A;<a href="#deployment-install">&#x5B8C;&#x6574;&#x7684;&#x53EF;&#x6267;&#x884C; jar &#x6587;&#x4EF6;</a>&#x4E2D;&#x7684;&#x7AEF;&#x70B9;&#xFF0C;&#x540C;&#x6837;&#xFF0C;&#x5F53;&#x8FD0;&#x884C;&#x4E00;&#x4E2A;&#x53EF;&#x6267;&#x884C;&#x7684; war &#x6587;&#x4EF6;&#x65F6;&#xFF0C;&#x5B83;&#x4E5F;&#x65E0;&#x6CD5;&#x626B;&#x63CF;&#x5305;&#x4E2D; <code>WEB-INF/classes</code> &#x4E0B;&#x7684;&#x7AEF;&#x70B9;&#x3002;&#x4E3A;&#x4E86;&#x907F;&#x514D;&#x8BE5;&#x9650;&#x5236;&#xFF0C;&#x60A8;&#x4E0D;&#x5E94;&#x8BE5;&#x4F7F;&#x7528; <code>packages</code> &#x65B9;&#x6CD5;&#xFF0C;&#x5E94;&#x8BE5;&#x4F7F;&#x7528;&#x4E0A;&#x8FF0;&#x7684; <code>register</code> &#x65B9;&#x6CD5;&#x6765;&#x5355;&#x72EC;&#x6CE8;&#x518C;&#x6BCF;&#x4E00;&#x4E2A;&#x7AEF;&#x70B9;&#x3002;</p>
</blockquote>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x6CE8;&#x518C;&#x4EFB;&#x610F;&#x6570;&#x91CF;&#x5B9E;&#x73B0;&#x4E86; <code>ResourceConfigCustomizer</code> &#x7684; bean&#xFF0C;&#x4EE5;&#x5B9E;&#x73B0;&#x66F4;&#x9AD8;&#x7EA7;&#x7684;&#x5B9A;&#x5236;&#x5316;&#x3002;</p>
<p>&#x6240;&#x6709;&#x6CE8;&#x518C;&#x7684;&#x7AEF;&#x70B9;&#x90FD;&#x5E94;&#x6CE8;&#x89E3;&#x4E86; <code>@Components</code> &#x5E76;&#x5177;&#x6709; HTTP &#x8D44;&#x6E90;&#x6CE8;&#x89E3;&#xFF08; <code>@GET</code> &#x7B49;&#xFF09;&#xFF0C;&#x4F8B;&#x5982;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token annotation punctuation">@Path</span><span class="token punctuation">(</span><span class="token string">&quot;/hello&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Endpoint</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@GET</span>
    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">message</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token string">&quot;Hello&quot;</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x7531;&#x4E8E; <code>Endpoint</code> &#x662F;&#x4E00;&#x4E2A; Spring <code>@Component</code>&#xFF0C;&#x5B83;&#x7684;&#x751F;&#x547D;&#x5468;&#x671F;&#x7531; Spring &#x7BA1;&#x7406;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@Autowired</code> &#x6CE8;&#x5165;&#x4F9D;&#x8D56;&#x5E76;&#x4F7F;&#x7528; <code>@Value</code> &#x6CE8;&#x5165;&#x5916;&#x90E8;&#x914D;&#x7F6E;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Jersey servlet &#x5C06;&#x88AB;&#x6CE8;&#x518C;&#x5E76;&#x6620;&#x5C04;&#x5230; <code>/*</code>&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5C06; <code>@ApplicationPath</code> &#x6DFB;&#x52A0;&#x5230; <code>ResourceConfig</code> &#x6765;&#x6539;&#x53D8;&#x6B64;&#x884C;&#x4E3A;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Jersey &#x5728; <code>ServletRegistrationBean</code> &#x7C7B;&#x578B;&#x7684; <code>@Bean</code> &#x4E2D;&#x88AB;&#x8BBE;&#x7F6E;&#x4E3A;&#x4E00;&#x4E2A;&#x540D;&#x4E3A; <code>jerseyServletRegistration</code> &#x7684; Servlet&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x8BE5; servlet &#x5C06;&#x88AB;&#x5EF6;&#x8FDF;&#x521D;&#x59CB;&#x5316;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.jersey.servlet.load-on-startup</code> &#x81EA;&#x5B9A;&#x4E49;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x7981;&#x7528;&#x6216;&#x901A;&#x8FC7;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x81EA;&#x5DF1;&#x7684;&#x540C;&#x540D; bean &#x6765;&#x8986;&#x76D6;&#x8BE5; bean&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>spring.jersey.type=filter</code> &#x4F7F;&#x7528;&#x8FC7;&#x6EE4;&#x5668;&#x66FF;&#x4EE3; servlet&#xFF08;&#x8BE5;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C; &#x66FF;&#x4EE3;&#x6216;&#x8986;&#x76D6; <code>@Bean</code> &#x7684;&#x4E3A;<code>jerseyFilterRegistration</code>&#xFF09;&#x3002;&#x8BE5;&#x8FC7;&#x6EE4;&#x5668;&#x6709;&#x4E00;&#x4E2A; <code>@Order</code>&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.jersey.filter.order</code> &#x8BBE;&#x7F6E;&#x3002;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.jersey.init.*</code> &#x6307;&#x5B9A;&#x4E00;&#x4E2A; map &#x7C7B;&#x578B;&#x7684; property &#x4EE5;&#x7ED9;&#x5B9A; servlet &#x548C;&#x8FC7;&#x6EE4;&#x5668;&#x7684;&#x521D;&#x59CB;&#x5316;&#x53C2;&#x6570;&#x3002;</p>
<p>&#x8FD9;&#x91CC;&#x6709;&#x4E00;&#x4E2A; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-samples/spring-boot-sample-jersey" target="_blank">Jersey &#x793A;&#x4F8B;</a>&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x89E3;&#x5982;&#x4F55;&#x8BBE;&#x7F6E;&#x3002;</p>
<p><a id="boot-features-embedded-container"></a></p>
<h3 id="284&#x3001;&#x5185;&#x5D4C;-servlet-&#x5BB9;&#x5668;&#x652F;&#x6301;">28.4&#x3001;&#x5185;&#x5D4C; Servlet &#x5BB9;&#x5668;&#x652F;&#x6301;</h3>
<p>Spring Boot &#x5305;&#x542B;&#x4E86;&#x5BF9;&#x5185;&#x5D4C; <a href="https://tomcat.apache.org/" target="_blank">Tomcat</a>&#x3001;<a href="https://www.eclipse.org/jetty/" target="_blank">Jetty</a> &#x548C; <a href="http://undertow.io/" target="_blank">Undertow</a> &#x670D;&#x52A1;&#x5668;&#x7684;&#x652F;&#x6301;&#x3002;&#x5927;&#x90E8;&#x5206;&#x5F00;&#x53D1;&#x4EBA;&#x5458;&#x53EA;&#x9700;&#x7B80;&#x5355;&#x5730;&#x4F7F;&#x7528;&#x5BF9;&#x5E94;&#x7684; Starter &#x6765;&#x83B7;&#x53D6;&#x5B8C;&#x6574;&#x7684;&#x914D;&#x7F6E;&#x5B9E;&#x4F8B;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5185;&#x5D4C;&#x670D;&#x52A1;&#x5668;&#x5C06;&#x76D1;&#x542C; <code>8080</code> &#x4E0A;&#x7684; HTTP &#x8BF7;&#x6C42;&#x3002;</p>
<p><strong>&#x8B66;&#x544A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x9009;&#x62E9;&#x5728; <a href="https://www.centos.org/" target="_blank">CentOS</a> &#x4F7F;&#x7528; Tomcat&#xFF0C;&#x8BF7;&#x6CE8;&#x610F;&#xFF0C;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x4E34;&#x65F6;&#x76EE;&#x5F55;&#x7528;&#x4E8E;&#x50A8;&#x5B58;&#x7F16;&#x8BD1;&#x540E;&#x7684; JSP&#x3001;&#x4E0A;&#x4F20;&#x7684;&#x6587;&#x4EF6;&#x7B49;&#x3002;&#x5F53;&#x60A8;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x8FD0;&#x884C;&#x65F6;&#x53D1;&#x751F;&#x4E86;&#x6545;&#x969C;&#xFF0C;&#x8BE5;&#x76EE;&#x5F55;&#x53EF;&#x80FD;&#x4F1A;&#x88AB; <code>tmpwatch</code> &#x5220;&#x9664;&#x3002;&#x4E3A;&#x4E86;&#x907F;&#x514D;&#x51FA;&#x73B0;&#x8BE5;&#x60C5;&#x51B5;&#xFF0C;&#x60A8;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x81EA;&#x5B9A;&#x4E49; <code>tmpwatch</code> &#x914D;&#x7F6E;&#xFF0C;&#x4F7F; <code>tomcat.*</code>&#x76EE;&#x5F55;&#x4E0D;&#x88AB;&#x5220;&#x9664;&#xFF0C;&#x6216;&#x8005;&#x914D;&#x7F6E; <code>server.tomcat.basedir</code> &#x8BA9; Tomcat &#x4F7F;&#x7528;&#x5176;&#x4ED6;&#x4F4D;&#x7F6E;&#x3002;</p>
</blockquote>
<p><a id="boot-features-embedded-container-servlets-filters-listeners"></a></p>
<h4 id="2841&#x3001;servlet&#x3001;filter-&#x4E0E;-listener">28.4.1&#x3001;Servlet&#x3001;Filter &#x4E0E; Listener</h4>
<p>&#x4F7F;&#x7528;&#x5185;&#x5D4C; servlet &#x5BB9;&#x5668;&#x65F6;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; Spring bean &#x6216;&#x8005;&#x626B;&#x63CF;&#x65B9;&#x5F0F;&#x6765;&#x6CE8;&#x518C; Servlet &#x89C4;&#x8303;&#x4E2D;&#x7684; Servlet&#x3001;Filter &#x548C;&#x6240;&#x6709;&#x76D1;&#x542C;&#x5668;&#xFF08;&#x6BD4;&#x5982; <code>HttpSessionListener</code>&#xFF09;&#x3002;</p>
<p><a id="boot-features-embedded-container-servlets-filters-listeners-beans"></a></p>
<h5 id="28411&#x3001;&#x5C06;-servlet&#x3001;filter-&#x548C;-listener-&#x6CE8;&#x518C;&#x4E3A;-spring-bean">28.4.1.1&#x3001;&#x5C06; Servlet&#x3001;Filter &#x548C; Listener &#x6CE8;&#x518C;&#x4E3A; Spring Bean</h5>
<p>&#x4EFB;&#x4F55; <code>Servlet</code>&#x3001;<code>Filter</code> &#x6216; <code>*Listener</code> &#x7684; Spring bean &#x5B9E;&#x4F8B;&#x90FD;&#x5C06;&#x88AB;&#x6CE8;&#x518C;&#x5230;&#x5185;&#x5D4C;&#x5BB9;&#x5668;&#x4E2D;&#x3002;&#x5982;&#x679C;&#x60A8;&#x60F3;&#x5F15;&#x7528; <code>application.properties</code> &#x4E2D;&#x7684;&#x67D0;&#x4E2A;&#x503C;&#xFF0C;&#x8FD9;&#x53EF;&#x80FD;&#x4F1A;&#x7279;&#x522B;&#x65B9;&#x4FBF;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5982;&#x679C;&#x4E0A;&#x4E0B;&#x6587;&#x53EA;&#x5305;&#x542B;&#x5355;&#x4E2A; Servlet&#xFF0C;&#x5B83;&#x5C06;&#x6620;&#x5C04;&#x5230; <code>/</code>&#x3002;&#x5728;&#x591A;&#x4E2A; Servlet bean &#x7684;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;bean &#x7684;&#x540D;&#x79F0;&#x5C06;&#x7528;&#x4F5C;&#x8DEF;&#x5F84;&#x7684;&#x524D;&#x7F00;&#x3002;Filter &#x5C06;&#x6620;&#x5C04;&#x5230; <code>/*</code>&#x3002;</p>
<p>&#x5982;&#x679C;&#x57FA;&#x4E8E;&#x7EA6;&#x5B9A;&#x914D;&#x7F6E;&#x7684;&#x6620;&#x5C04;&#x4E0D;&#x591F;&#x7075;&#x6D3B;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>ServletRegistrationBean</code>&#x3001;<code>FilterRegistrationBean</code> &#x548C; <code>ServletListenerRegistrationBean</code> &#x7C7B;&#x6765;&#x5B8C;&#x5168;&#x63A7;&#x5236;&#x3002;</p>
<p>Spring Boot &#x9644;&#x5E26;&#x4E86;&#x8BB8;&#x591A;&#x53EF;&#x4EE5;&#x5B9A;&#x4E49; Filter bean &#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x4EE5;&#x4E0B;&#x662F;&#x90E8;&#x5206;&#x8FC7;&#x6EE4;&#x5668;&#x53CA;&#x5176;&#x6267;&#x884C;&#x987A;&#x5E8F;&#x7684;&#xFF08;&#x987A;&#x5E8F;&#x503C;&#x8D8A;&#x4F4E;&#xFF0C;&#x4F18;&#x5148;&#x7EA7;&#x8D8A;&#x9AD8;&#xFF09;&#xFF1A;</p>
<table>
<thead>
<tr>
<th>Servlet Filter</th>
<th>&#x987A;&#x5E8F;</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>OrderedCharacterEncodingFilter</code></td>
<td><code>Ordered.HIGHEST_PRECEDENCE</code></td>
</tr>
<tr>
<td><code>WebMvcMetricsFilter</code></td>
<td><code>Ordered.HIGHEST_PRECEDENCE + 1</code></td>
</tr>
<tr>
<td><code>ErrorPageFilter</code></td>
<td><code>Ordered.HIGHEST_PRECEDENCE + 1</code></td>
</tr>
<tr>
<td><code>HttpTraceFilter</code></td>
<td><code>Ordered.LOWEST_PRECEDENCE - 10</code></td>
</tr>
</tbody>
</table>
<p>&#x901A;&#x5E38; Filter bean &#x65E0;&#x5E8F;&#x653E;&#x7F6E;&#x4E5F;&#x662F;&#x5B89;&#x5168;&#x7684;&#x3002;</p>
<p>&#x5982;&#x679C;&#x9700;&#x8981;&#x6307;&#x5B9A;&#x987A;&#x5E8F;&#xFF0C;&#x5219;&#x5E94;&#x907F;&#x514D;&#x5728; <code>Ordered.HIGHEST_PRECEDENCE</code> &#x987A;&#x5E8F;&#x70B9;&#x914D;&#x7F6E;&#x8BFB;&#x53D6;&#x8BF7;&#x6C42;&#x4F53;&#x7684;&#x8FC7;&#x6EE4;&#x5668;&#xFF0C;&#x56E0;&#x4E3A;&#x5B83;&#x7684;&#x5B57;&#x7B26;&#x7F16;&#x7801;&#x53EF;&#x80FD;&#x4E0E;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x5B57;&#x7B26;&#x7F16;&#x7801;&#x914D;&#x7F6E;&#x4E0D;&#x4E00;&#x81F4;&#x3002;&#x5982;&#x679C;&#x4E00;&#x4E2A; Servlet &#x8FC7;&#x6EE4;&#x5668;&#x5305;&#x88C5;&#x4E86;&#x8BF7;&#x6C42;&#xFF0C;&#x5219;&#x5E94;&#x4F7F;&#x7528;&#x5C0F;&#x4E8E;&#x6216;&#x7B49;&#x4E8E; <code>OrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER</code>&#x7684;&#x987A;&#x5E8F;&#x70B9;&#x5BF9;&#x5176;&#x8FDB;&#x884C;&#x914D;&#x7F6E;&#x3002;</p>
<p><a id="boot-features-embedded-container-context-initializer"></a></p>
<h4 id="2842&#x3001;servlet-&#x4E0A;&#x4E0B;&#x6587;&#x521D;&#x59CB;&#x5316;">28.4.2&#x3001;Servlet &#x4E0A;&#x4E0B;&#x6587;&#x521D;&#x59CB;&#x5316;</h4>
<p>&#x5185;&#x5D4C; servlet &#x5BB9;&#x5668;&#x4E0D;&#x4F1A;&#x76F4;&#x63A5;&#x6267;&#x884C; Servlet 3.0+ &#x7684; <code>javax.servlet.ServletContainerInitializer</code> &#x63A5;&#x53E3;&#x6216; Spring &#x7684; <code>org.springframework.web.WebApplicationInitializer</code> &#x63A5;&#x53E3;&#x3002;&#x8FD9;&#x662F;&#x4E00;&#x4E2A;&#x6709;&#x610F;&#x7684;&#x8BBE;&#x8BA1;&#x51B3;&#x7B56;&#xFF0C;&#x65E8;&#x5728;&#x964D;&#x4F4E;&#x5728; war &#x5185;&#x8FD0;&#x884C;&#x65F6;&#x7B2C;&#x4E09;&#x65B9;&#x7C7B;&#x5E93;&#x4EA7;&#x751F;&#x7684;&#x98CE;&#x9669;&#xFF0C;&#x9632;&#x6B62;&#x7834;&#x574F; Sring Boot &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x5728; Spring Boot &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x6267;&#x884C; servlet &#x4E0A;&#x4E0B;&#x6587;&#x521D;&#x59CB;&#x5316;&#xFF0C;&#x5219;&#x5E94;&#x6CE8;&#x518C;&#x4E00;&#x4E2A;&#x5B9E;&#x73B0;&#x4E86; <code>org.springframework.boot.context.embedded.ServletContextInitializer</code> &#x63A5;&#x53E3;&#x7684; bean&#x3002;<code>onStartup</code> &#x65B9;&#x6CD5;&#x63D0;&#x4F9B;&#x4E86;&#x9488;&#x5BF9; <code>ServletContext</code> &#x7684;&#x8BBF;&#x95EE;&#x5165;&#x53E3;&#xFF0C;&#x5982;&#x679C;&#x9700;&#x8981;&#xFF0C;&#x5B83;&#x53EF;&#x4EE5;&#x5BB9;&#x6613;&#x4F5C;&#x4E3A;&#x73B0;&#x6709; <code>WebApplicationInitializer</code> &#x7684;&#x9002;&#x914D;&#x5668;&#x3002;</p>
<p><a id="boot-features-embedded-container-servlets-filters-listeners-scanning"></a></p>
<h5 id="28421&#x3001;&#x626B;&#x63CF;-servlet&#x3001;filter-&#x548C;-listener">28.4.2.1&#x3001;&#x626B;&#x63CF; Servlet&#x3001;Filter &#x548C; Listener</h5>
<p>&#x4F7F;&#x7528;&#x5185;&#x5D4C;&#x5BB9;&#x5668;&#x65F6;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@ServletComponentScan</code> &#x542F;&#x7528;&#x5E26; <code>@WebServlet</code>&#x3001;<code>@WebFilter</code> &#x548C; <code>@WebListener</code> &#x6CE8;&#x89E3;&#x7684;&#x7C7B;&#x81EA;&#x52A8;&#x6CE8;&#x518C;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<p><code>@ServletComponentScan</code> &#x5728;&#x72EC;&#x7ACB;&#xFF08;standalone&#xFF09;&#x5BB9;&#x5668;&#x4E2D;&#x4E0D;&#x8D77;&#x4F5C;&#x7528;&#xFF0C;&#x56E0;&#x5BB9;&#x5668;&#x5C06;&#x4F7F;&#x7528;&#x5185;&#x7F6E;&#x53D1;&#x73B0;&#x673A;&#x5236;&#x6765;&#x4EE3;&#x66FF;&#x3002;</p>
<p><a id="boot-features-embedded-container-application-context"></a></p>
<h4 id="2843&#x3001;servletwebserverapplicationcontext">28.4.3&#x3001;ServletWebServerApplicationContext</h4>
<p>Spring Boot &#x5E95;&#x5C42;&#x4F7F;&#x7528;&#x4E86;&#x4E00;&#x4E2A;&#x4E0D;&#x540C;&#x7684; <code>ApplicationContext</code> &#x7C7B;&#x578B;&#x6765;&#x652F;&#x6301;&#x5185;&#x5D4C; servlet&#x3002;<code>ServletWebServerApplicationContext</code> &#x662F;&#x4E00;&#x4E2A;&#x7279;&#x6B8A; <code>WebApplicationContext</code> &#x7C7B;&#x578B;&#xFF0C;&#x5B83;&#x901A;&#x8FC7;&#x641C;&#x7D22;&#x5355;&#x4E2A; <code>ServletWebServerFactory</code> bean &#x6765;&#x5F15;&#x5BFC;&#x81EA;&#x8EAB;&#x3002;&#x901A;&#x5E38;&#xFF0C;<code>TomcatServletWebServerFactory</code>&#x3001; <code>JettyServletWebServerFactory</code> &#x6216;&#x8005; <code>UndertowServletWebServerFactory</code> &#x4E2D;&#x7684;&#x4E00;&#x4E2A;&#x5C06;&#x88AB;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x901A;&#x5E38;&#xFF0C;&#x4F60;&#x4E0D;&#x9700;&#x8981;&#x77E5;&#x9053;&#x8FD9;&#x4E9B;&#x5B9E;&#x73B0;&#x7C7B;&#x3002;&#x5927;&#x90E8;&#x5206;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x5E76;&#x4E3A;&#x60A8;&#x521B;&#x5EFA;&#x5408;&#x9002;&#x7684; <code>ApplicationContext</code> &#x548C; <code>ServletWebServerFactory</code>&#x3002;</p>
</blockquote>
<p><a id="boot-features-customizing-embedded-containers"></a></p>
<h5 id="2844&#x3001;&#x81EA;&#x5B9A;&#x4E49;&#x5185;&#x5D4C;-servlet-&#x5BB9;&#x5668;">28.4.4&#x3001;&#x81EA;&#x5B9A;&#x4E49;&#x5185;&#x5D4C; Servlet &#x5BB9;&#x5668;</h5>
<p>&#x53EF;&#x4EE5;&#x4F7F;&#x7528; Spring <code>Environment</code> &#x5C5E;&#x6027;&#x6765;&#x914D;&#x7F6E;&#x901A;&#x7528;&#x7684; servlet &#x5BB9;&#x5668;&#x8BBE;&#x7F6E;&#x3002;&#x901A;&#x5E38;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>application.properties</code> &#x6587;&#x4EF6;&#x4E2D;&#x5B9A;&#x4E49;&#x8FD9;&#x4E9B;&#x5C5E;&#x6027;&#x3002;</p>
<p>&#x901A;&#x7528;&#x7684;&#x670D;&#x52A1;&#x5668;&#x8BBE;&#x7F6E;&#x5305;&#x62EC;&#xFF1A;</p>
<ul>
<li>&#x7F51;&#x7EDC;&#x8BBE;&#x7F6E;&#xFF1A;&#x76D1;&#x542C; HTTP &#x8BF7;&#x6C42;&#x7684;&#x7AEF;&#x53E3;&#xFF08;<code>server.port</code>&#xFF09;&#xFF0C;&#x7ED1;&#x5B9A;&#x63A5;&#x53E3;&#x5730;&#x5740;&#x5230; <code>server.address</code> &#x7B49;&#x3002;</li>
<li>&#x4F1A;&#x8BDD;&#x8BBE;&#x7F6E;&#xFF1A;&#x662F;&#x5426;&#x6301;&#x4E45;&#x4F1A;&#x8BDD;&#xFF08;<code>server.session.persistence</code>&#xFF09;&#x3001;session &#x8D85;&#x65F6;&#xFF08;<code>server.session.timeout</code>&#xFF09;&#x3001;&#x4F1A;&#x8BDD;&#x6570;&#x636E;&#x5B58;&#x653E;&#x4F4D;&#x7F6E;&#xFF08;<code>server.session.store-dir</code>&#xFF09;&#x548C; session-cookie &#x914D;&#x7F6E;&#xFF08;<code>server.session.cookie.*</code>&#xFF09;&#x3002;</li>
<li>&#x9519;&#x8BEF;&#x7BA1;&#x7406;&#xFF1A;&#x9519;&#x8BEF;&#x9875;&#x9762;&#x4F4D;&#x7F6E;&#xFF08;<code>server.error.path</code>&#xFF09;&#x7B49;&#x3002;</li>
<li><a href="#howto-configure-ssl">SSL</a></li>
<li><a href="#how-to-enable-http-response-compression">HTTP &#x538B;&#x7F29;</a></li>
</ul>
<p>Spring Boot &#x5C3D;&#x53EF;&#x80FD;&#x66B4;&#x9732;&#x901A;&#x7528;&#x7684;&#x8BBE;&#x7F6E;&#xFF0C;&#x4F46;&#x5E76;&#x4E0D;&#x603B;&#x662F;&#x90FD;&#x53EF;&#x4EE5;&#x3002;&#x9488;&#x5BF9;&#x8FD9;&#x4E9B;&#x60C5;&#x51B5;&#xFF0C;&#x4E13;&#x7528;&#x7684;&#x547D;&#x540D;&#x7A7A;&#x95F4;&#x4E3A;&#x7279;&#x5B9A;&#x7684;&#x670D;&#x52A1;&#x5668;&#x63D0;&#x4F9B;&#x4E86;&#x81EA;&#x5B9A;&#x4E49;&#x529F;&#x80FD;&#xFF08;&#x8BF7;&#x53C2;&#x9605; <code>server.tomcat</code> &#x548C; <code>server.undertow</code>&#xFF09;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x5185;&#x5D4C; servlet &#x5BB9;&#x5668;&#x7684;&#x7279;&#x5B9A;&#x529F;&#x80FD;&#x6765;&#x914D;&#x7F6E;<a href="#howto-configure-accesslogs">&#x8BBF;&#x95EE;&#x65E5;&#x5FD7;</a>&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6709;&#x5173;&#x5B8C;&#x6574;&#x7684;&#x5185;&#x5BB9;&#x5217;&#x8868;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ServerProperties.java" target="_blank">ServerProperties</a> &#x7C7B;&#x3002;</p>
</blockquote>
<p><a id="boot-features-programmatic-embedded-container-customization"></a></p>
<h6 id="28441&#x3001;&#x4EE5;&#x7F16;&#x7A0B;&#x65B9;&#x5F0F;&#x81EA;&#x5B9A;&#x4E49;">28.4.4.1&#x3001;&#x4EE5;&#x7F16;&#x7A0B;&#x65B9;&#x5F0F;&#x81EA;&#x5B9A;&#x4E49;</h6>
<p>&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x4EE5;&#x7F16;&#x7A0B;&#x7684;&#x65B9;&#x5F0F;&#x914D;&#x7F6E;&#x5185;&#x5D4C; servlet &#x5BB9;&#x5668;&#xFF0C;&#x53EF;&#x4EE5;&#x6CE8;&#x518C;&#x4E00;&#x4E2A;&#x662F;&#x5B9E;&#x73B0;&#x4E86; <code>WebServerFactoryCustomizer</code> &#x63A5;&#x53E3;&#x7684; Spring bean&#x3002;<code>WebServerFactoryCustomizer</code> &#x63D0;&#x4F9B;&#x4E86;&#x5BF9; <code>ConfigurableServletWebServerFactory</code> &#x7684;&#x8BBF;&#x95EE;&#x5165;&#x53E3;&#xFF0C;&#x5176;&#x4E2D;&#x5305;&#x542B;&#x4E86;&#x8BB8;&#x591A;&#x81EA;&#x5B9A;&#x4E49; setter &#x65B9;&#x6CD5;&#x3002;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x4F7F;&#x7528;&#x4E86;&#x7F16;&#x7A0B;&#x65B9;&#x5F0F;&#x6765;&#x8BBE;&#x7F6E;&#x7AEF;&#x53E3;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>web<span class="token punctuation">.</span>server</span><span class="token punctuation">.</span><span class="token class-name">WebServerFactoryCustomizer</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>web<span class="token punctuation">.</span>servlet<span class="token punctuation">.</span>server</span><span class="token punctuation">.</span><span class="token class-name">ConfigurableServletWebServerFactory</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype</span><span class="token punctuation">.</span><span class="token class-name">Component</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">CustomizationBean</span> <span class="token keyword">implements</span> <span class="token class-name">WebServerFactoryCustomizer</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">ConfigurableServletWebServerFactory</span><span class="token punctuation">&gt;</span></span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">customize</span><span class="token punctuation">(</span><span class="token class-name">ConfigurableServletWebServerFactory</span> server<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        server<span class="token punctuation">.</span><span class="token function">setPort</span><span class="token punctuation">(</span><span class="token number">9000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p><code>TomcatServletWebServerFactory</code>&#x3001;<code>JettyServletWebServerFactory</code> &#x548C; <code>UndertowServletWebServerFactory</code> &#x662F; ConfigurableServletWebServerFactory &#x7684;&#x5177;&#x4F53;&#x5B50;&#x7C7B;&#xFF0C;&#x5B83;&#x4EEC;&#x5206;&#x522B;&#x4E3A; Tomcat&#x3001;Jetty &#x548C; Undertow &#x63D0;&#x4F9B;&#x4E86;&#x989D;&#x5916;&#x7684;&#x81EA;&#x5B9A;&#x4E49; setter &#x65B9;&#x6CD5;&#x3002;</p>
</blockquote>
<p><a id="boot-features-customizing-configurableservletwebserverfactory-directly"></a></p>
<h6 id="28442&#x3001;&#x76F4;&#x63A5;&#x81EA;&#x5B9A;&#x4E49;-configurableservletwebserverfactory">28.4.4.2&#x3001;&#x76F4;&#x63A5;&#x81EA;&#x5B9A;&#x4E49; ConfigurableServletWebServerFactory</h6>
<p>&#x5982;&#x679C;&#x4E0A;&#x8FF0;&#x7684;&#x81EA;&#x5B9A;&#x4E49;&#x65B9;&#x5F0F;&#x592A;&#x5C40;&#x9650;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x81EA;&#x5DF1;&#x6CE8;&#x518C; <code>TomcatServletWebServerFactory</code>&#x3001;<code>JettyServletWebServerFactory</code> &#x6216; <code>UndertowServletWebServerFactory</code> bean&#x3002;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">ConfigurableServletWebServerFactory</span> <span class="token function">webServerFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token class-name">TomcatServletWebServerFactory</span> factory <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">TomcatServletWebServerFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    factory<span class="token punctuation">.</span><span class="token function">setPort</span><span class="token punctuation">(</span><span class="token number">9000</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    factory<span class="token punctuation">.</span><span class="token function">setSessionTimeout</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token class-name">TimeUnit</span><span class="token punctuation">.</span>MINUTES<span class="token punctuation">)</span><span class="token punctuation">;</span>
    factory<span class="token punctuation">.</span><span class="token function">addErrorPages</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">ErrorPage</span><span class="token punctuation">(</span><span class="token class-name">HttpStatus</span><span class="token punctuation">.</span>NOT_FOUND<span class="token punctuation">,</span> <span class="token string">&quot;/notfound.html&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token keyword">return</span> factory<span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>Setter &#x65B9;&#x6CD5;&#x63D0;&#x4F9B;&#x4E86;&#x8BB8;&#x591A;&#x914D;&#x7F6E;&#x9009;&#x9879;&#x3002;&#x8FD8;&#x6709;&#x51E0;&#x4E2A; <strong>hook</strong> &#x4FDD;&#x62A4;&#x65B9;&#x6CD5;&#x4F9B;&#x60A8;&#x6DF1;&#x5165;&#x5B9A;&#x5236;&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605;<a href="https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/api/org/springframework/boot/web/servlet/server/ConfigurableServletWebServerFactory.html" target="_blank">&#x6E90;&#x7801;&#x6587;&#x6863;</a>&#x3002;</p>
<p><a id="boot-features-jsp-limitations"></a></p>
<h4 id="2845&#x3001;jsp-&#x5C40;&#x9650;">28.4.5&#x3001;JSP &#x5C40;&#x9650;</h4>
<p>&#x5F53;&#x8FD0;&#x884C;&#x4F7F;&#x7528;&#x4E86;&#x5185;&#x5D4C; servlet &#x5BB9;&#x5668;&#x7684; Spring Boot &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x65F6;&#xFF08;&#x6253;&#x5305;&#x4E3A;&#x53EF;&#x6267;&#x884C;&#x5F52;&#x6863;&#x6587;&#x4EF6;&#xFF09;&#xFF0C;JSP &#x652F;&#x6301;&#x5C06;&#x5B58;&#x5728;&#x4E00;&#x4E9B;&#x9650;&#x5236;&#x3002;</p>
<ul>
<li>&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528; war &#x6253;&#x5305;&#xFF0C;&#x5728; Jetty &#x548C; Tomcat &#x4E2D;&#x53EF;&#x4EE5;&#x6B63;&#x5E38;&#x5DE5;&#x4F5C;&#xFF0C;&#x4F7F;&#x7528; <code>java -jar</code> &#x542F;&#x52A8;&#x65F6;&#xFF0C;&#x53EF;&#x6267;&#x884C;&#x7684; war &#x53EF;&#x6B63;&#x5E38;&#x4F7F;&#x7528;&#xFF0C;&#x5E76;&#x4E14;&#x8FD8;&#x53EF;&#x4EE5;&#x90E8;&#x7F72;&#x5230;&#x4EFB;&#x4F55;&#x6807;&#x51C6;&#x5BB9;&#x5668;&#x3002;&#x4F7F;&#x7528;&#x53EF;&#x6267;&#x884C; jar &#x65F6;&#x4E0D;&#x652F;&#x6301; JSP&#x3002;</li>
<li>Undertow &#x4E0D;&#x652F;&#x6301; JSP&#x3002;</li>
<li>&#x521B;&#x5EFA;&#x81EA;&#x5B9A;&#x4E49;&#x7684; error.jsp &#x9875;&#x9762;&#x4E0D;&#x4F1A;&#x8986;&#x76D6;&#x9ED8;&#x8BA4;<a href="#boot-features-error-handling">&#x9519;&#x8BEF;&#x5904;&#x7406;</a>&#x89C6;&#x56FE;&#xFF0C;&#x5E94;&#x8BE5;&#x4F7F;&#x7528;<a href="#boot-features-error-handling-custom-error-pages">&#x81EA;&#x5B9A;&#x4E49;&#x9519;&#x8BEF;&#x9875;&#x9762;</a>&#x6765;&#x4EE3;&#x66FF;&#x3002;</li>
</ul>
<p>&#x8FD9;&#x91CC;&#x6709;&#x4E00;&#x4E2A; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-samples/spring-boot-sample-web-jsp" target="_blank">JSP &#x793A;&#x4F8B;</a>&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4E86;&#x89E3;&#x5230;&#x5982;&#x4F55;&#x914D;&#x7F6E;&#x3002;</p>
<p><a id="boot-features-reactive-server"></a></p>
<h3 id="285&#x3001;&#x5185;&#x5D4C;&#x54CD;&#x5E94;&#x5F0F;&#x670D;&#x52A1;&#x5668;&#x652F;&#x6301;">28.5&#x3001;&#x5185;&#x5D4C;&#x54CD;&#x5E94;&#x5F0F;&#x670D;&#x52A1;&#x5668;&#x652F;&#x6301;</h3>
<p>Spring Boot &#x5305;&#x62EC;&#x5BF9;&#x4EE5;&#x4E0B;&#x5185;&#x5D4C;&#x54CD;&#x5E94;&#x5F0F; Web &#x670D;&#x52A1;&#x5668;&#x7684;&#x652F;&#x6301;&#xFF1A;Reactor Netty&#x3001;Tomcat&#x3001;Jetty &#x548C; Undertow&#x3002;&#x5927;&#x591A;&#x6570;&#x5F00;&#x53D1;&#x4EBA;&#x5458;&#x4F7F;&#x7528;&#x5BF9;&#x5E94;&#x7684; <strong>Starter</strong> &#x6765;&#x83B7;&#x53D6;&#x4E00;&#x4E2A;&#x5B8C;&#x5168;&#x914D;&#x7F6E;&#x7684;&#x5B9E;&#x4F8B;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5185;&#x5D4C;&#x670D;&#x52A1;&#x5668;&#x5728; 8080 &#x7AEF;&#x53E3;&#x4E0A;&#x76D1;&#x542C; HTTP &#x8BF7;&#x6C42;&#x3002;</p>
<p><a id="boot-features-reactive-server-resources"></a></p>
<h3 id="286&#x3001;&#x54CD;&#x5E94;&#x5F0F;&#x670D;&#x52A1;&#x5668;&#x8D44;&#x6E90;&#x914D;&#x7F6E;">28.6&#x3001;&#x54CD;&#x5E94;&#x5F0F;&#x670D;&#x52A1;&#x5668;&#x8D44;&#x6E90;&#x914D;&#x7F6E;</h3>
<p>&#x5728;&#x81EA;&#x52A8;&#x914D;&#x7F6E; Reactor Netty &#x6216; Jetty &#x670D;&#x52A1;&#x5668;&#x65F6;&#xFF0C;Spring Boot &#x5C06;&#x521B;&#x5EFA;&#x7279;&#x5B9A;&#x7684; bean &#x4E3A;&#x670D;&#x52A1;&#x5668;&#x5B9E;&#x4F8B;&#x63D0;&#x4F9B; HTTP &#x8D44;&#x6E90;&#xFF1A;<code>ReactorResourceFactory</code> &#x6216; <code>JettyResourceFactory</code>&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x8FD9;&#x4E9B;&#x8D44;&#x6E90;&#x4E5F;&#x5C06;&#x4E0E; Reactor Netty &#x548C; Jetty &#x5BA2;&#x6237;&#x7AEF;&#x5171;&#x4EAB;&#x4EE5;&#x83B7;&#x5F97;&#x6700;&#x4F73;&#x6027;&#x80FD;&#xFF0C;&#x5177;&#x4F53;&#x5982;&#x4E0B;&#xFF1A;</p>
<ul>
<li>&#x7528;&#x4E8E;&#x670D;&#x52A1;&#x5668;&#x548C;&#x5BA2;&#x6237;&#x7AEF;&#x7684;&#x7684;&#x76F8;&#x540C;&#x6280;&#x672F;</li>
<li>&#x5BA2;&#x6237;&#x7AEF;&#x5B9E;&#x4F8B;&#x4F7F;&#x7528;&#x4E86; Spring Boot &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>WebClient.Builder</code> bean &#x6784;&#x5EFA;&#x3002;</li>
</ul>
<p>&#x5F00;&#x53D1;&#x4EBA;&#x5458;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x63D0;&#x4F9B;&#x81EA;&#x5B9A;&#x4E49;&#x7684; <code>ReactorResourceFactory</code> &#x6216; <code>JettyResourceFactory</code> bean &#x6765;&#x91CD;&#x5199; Jetty &#x548C; Reactor Netty &#x7684;&#x8D44;&#x6E90;&#x914D;&#x7F6E; &#x2014;&#x2014; &#x5C06;&#x5E94;&#x7528;&#x4E8E;&#x5BA2;&#x6237;&#x7AEF;&#x548C;&#x670D;&#x52A1;&#x5668;&#x3002;</p>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x5728; <a href="#boot-features-webclient-runtime">WebClient Runtime</a> &#x7AE0;&#x8282;&#x4E2D;&#x4E86;&#x89E3;&#x6709;&#x5173;&#x5BA2;&#x6237;&#x7AEF;&#x8D44;&#x6E90;&#x914D;&#x7F6E;&#x7684;&#x66F4;&#x591A;&#x5185;&#x5BB9;&#x3002;</p>
<p><a id="boot-features-security"></a></p>
<h2 id="29&#x3001;&#x5B89;&#x5168;">29&#x3001;&#x5B89;&#x5168;</h2>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5982;&#x679C; <a href="https://projects.spring.io/spring-security/" target="_blank">Spring Security</a> &#x5728; classpath &#x4E0A;&#xFF0C;&#x5219; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x662F;&#x53D7;&#x4FDD;&#x62A4;&#x7684;&#x3002;Spring Boot &#x4F9D;&#x8D56; Spring Security &#x7684;&#x5185;&#x5BB9;&#x534F;&#x5546;&#x7B56;&#x7565;&#x6765;&#x786E;&#x5B9A;&#x662F;&#x4F7F;&#x7528; <code>httpBasic</code> &#x8FD8;&#x662F; <code>formLogin</code>&#x3002;&#x8981;&#x7ED9; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x6DFB;&#x52A0;&#x65B9;&#x6CD5;&#x7EA7;&#x522B;&#x7684;&#x5B89;&#x5168;&#x4FDD;&#x62A4;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@EnableGlobalMethodSecurity</code> &#x6CE8;&#x89E3;&#x8BBE;&#x7F6E;&#x3002;&#x6709;&#x5173;&#x66F4;&#x591A;&#x5176;&#x4ED6;&#x4FE1;&#x606F;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <a href="https://docs.spring.io/spring-security/site/docs/5.1.2.RELEASE/reference/htmlsingle#jc-method" target="_blank">Spring Security &#x53C2;&#x8003;&#x6307;&#x5357;</a>&#x4E2D;&#x627E;&#x5230;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x7684; <code>UserDetailsS&#x200B;&#x200B;ervice</code> &#x53EA;&#x6709;&#x4E00;&#x4E2A;&#x7528;&#x6237;&#x3002;&#x7528;&#x6237;&#x540D;&#x4E3A; <code>user</code>&#xFF0C;&#x5BC6;&#x7801;&#x662F;&#x968F;&#x673A;&#x7684;&#xFF0C;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x542F;&#x52A8;&#x65F6;&#x4F1A;&#x4EE5; INFO &#x7EA7;&#x522B;&#x6253;&#x5370;&#x51FA;&#x6765;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code>Using generated security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35
</code></pre><p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x5BF9;&#x65E5;&#x5FD7;&#x914D;&#x7F6E;&#x8FDB;&#x884C;&#x5FAE;&#x8C03;&#xFF0C;&#x8BF7;&#x786E;&#x4FDD;&#x5C06; <code>org.springframework.boot.autoconfigure.security</code> &#x7684;&#x7EA7;&#x522B;&#x8BBE;&#x7F6E;&#x4E3A; <code>INFO</code>&#x3002;&#x5426;&#x5219;&#xFF0C;&#x9ED8;&#x8BA4;&#x5BC6;&#x7801;&#x4E0D;&#x4F1A;&#x6253;&#x5370;&#x51FA;&#x6765;&#x3002;</p>
</blockquote>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x63D0;&#x4F9B; <code>spring.security.user.name</code> &#x548C; <code>spring.security.user.password</code> &#x6765;&#x66F4;&#x6539;&#x7528;&#x6237;&#x540D;&#x548C;&#x5BC6;&#x7801;&#x3002;</p>
<p>&#x60A8;&#x5728; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x9ED8;&#x8BA4;&#x4F1A;&#x83B7;&#x5F97;&#x4EE5;&#x4E0B;&#x57FA;&#x672C;&#x529F;&#x80FD;&#xFF1A;</p>
<ul>
<li>&#x4E00;&#x4E2A; <code>UserDetailsS&#x200B;&#x200B;ervice</code>&#xFF08;&#x6216; WebFlux &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x7684; <code>ReactiveUserDetailsS&#x200B;&#x200B;ervice</code>&#xFF09;bean&#xFF0C;&#x91C7;&#x7528;&#x5185;&#x5B58;&#x5B58;&#x50A8;&#x5F62;&#x5F0F;&#xFF0C;&#x6709;&#x4E00;&#x4E2A;&#x81EA;&#x52A8;&#x751F;&#x6210;&#x5BC6;&#x7801;&#x7684;&#x7528;&#x6237;&#xFF08;&#x6709;&#x5173;&#x7528;&#x6237;&#x5C5E;&#x6027;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/api/org/springframework/boot/autoconfigure/security/SecurityProperties.User.html" target="_blank"><code>SecurityProperties.User</code></a>&#xFF09;&#x3002;</li>
<li>&#x7528;&#x4E8E;&#x6574;&#x4E2A;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF08;&#x5982;&#x679C; actuator &#x5728; classpath &#x4E0A;&#xFF0C;&#x5219;&#x5305;&#x62EC; actuator &#x7AEF;&#x70B9;&#xFF09;&#x57FA;&#x4E8E;&#x8868;&#x5355;&#x767B;&#x5F55;&#x6216; HTTP Basic &#x8BA4;&#x8BC1;&#xFF08;&#x53D6;&#x51B3;&#x4E8E; Content-Type&#xFF09;&#x3002;</li>
<li>&#x4E00;&#x4E2A;&#x7528;&#x4E8E;&#x53D1;&#x5E03;&#x8EAB;&#x4EFD;&#x9A8C;&#x8BC1;&#x4E8B;&#x4EF6;&#x7684; <code>DefaultAuthenticationEventPublisher</code>&#x3002;</li>
</ul>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4E3A;&#x5176;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A; bean &#x6765;&#x63D0;&#x4F9B;&#x4E0D;&#x540C;&#x7684; <code>AuthenticationEventPublisher</code>&#x3002;</p>
<p><a id="boot-features-security-mvc"></a></p>
<h3 id="291&#x3001;mvc-&#x5B89;&#x5168;">29.1&#x3001;MVC &#x5B89;&#x5168;</h3>
<p>&#x9ED8;&#x8BA4;&#x7684;&#x5B89;&#x5168;&#x914D;&#x7F6E;&#x5728; <code>SecurityAutoConfiguration</code> &#x548C; <code>UserDetailsS&#x200B;&#x200B;erviceAutoConfiguration</code> &#x4E2D;&#x5B9E;&#x73B0;&#x3002; <code>SecurityAutoConfiguration</code> &#x5BFC;&#x5165;&#x7528;&#x4E8E; Web &#x5B89;&#x5168;&#x7684; <code>SpringBootWebSecurityConfiguration</code>&#xFF0C;<code>UserDetailsS&#x200B;&#x200B;erviceAutoConfiguration</code> &#x914D;&#x7F6E;&#x8EAB;&#x4EFD;&#x9A8C;&#x8BC1;&#xFF0C;&#x8FD9;&#x540C;&#x6837;&#x9002;&#x7528;&#x4E8E;&#x975E; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;&#x8981;&#x5B8C;&#x5168;&#x5173;&#x95ED;&#x9ED8;&#x8BA4;&#x7684; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5B89;&#x5168;&#x914D;&#x7F6E;&#xFF0C;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0; <code>WebSecurityConfigurerAdapter</code> &#x7C7B;&#x578B;&#x7684; bean&#xFF08;&#x8FD9;&#x6837;&#x505A;&#x4E0D;&#x4F1A;&#x7981;&#x7528; <code>UserDetailsS&#x200B;&#x200B;ervice</code> &#x914D;&#x7F6E;&#x6216; Actuator &#x7684;&#x5B89;&#x5168;&#x4FDD;&#x62A4;&#xFF09;&#x3002;</p>
<p>&#x8981;&#x540C;&#x65F6;&#x5173;&#x95ED; <code>UserDetailsS&#x200B;&#x200B;ervice</code> &#x914D;&#x7F6E;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0; <code>UserDetailsS&#x200B;&#x200B;ervice</code>&#x3001;<code>AuthenticationProvider</code> &#x6216; <code>AuthenticationManager</code> &#x7C7B;&#x578B;&#x7684; bean&#x3002;<a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-samples/" target="_blank">Spring Boot &#x793A;&#x4F8B;</a>&#x4E2D;&#x6709;&#x51E0;&#x4E2A;&#x4F7F;&#x7528;&#x4E86;&#x5B89;&#x5168;&#x4FDD;&#x62A4;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;&#x4ED6;&#x4EEC;&#x6216;&#x8BB8;&#x53EF;&#x4EE5;&#x5E2E;&#x52A9;&#x5230;&#x60A8;&#x3002;</p>
<p>&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6DFB;&#x52A0;&#x81EA;&#x5B9A;&#x4E49; <code>WebSecurityConfigurerAdapter</code> &#x6765;&#x91CD;&#x5199;&#x8BBF;&#x95EE;&#x89C4;&#x5219;&#x3002;Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x4FBF;&#x6377;&#x65B9;&#x6CD5;&#xFF0C;&#x53EF;&#x7528;&#x4E8E;&#x91CD;&#x5199; actuator &#x7AEF;&#x70B9;&#x548C;&#x9759;&#x6001;&#x8D44;&#x6E90;&#x7684;&#x8BBF;&#x95EE;&#x89C4;&#x5219;&#x3002;<code>EndpointRequest</code> &#x53EF;&#x7528;&#x4E8E;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x57FA;&#x4E8E; <code>management.endpoints.web.base-path</code> &#x5C5E;&#x6027;&#x7684; <code>RequestMatcher</code>&#x3002;<code>PathRequest</code> &#x53EF;&#x7528;&#x4E8E;&#x4E3A;&#x5E38;&#x7528;&#x4F4D;&#x7F6E;&#x4E2D;&#x7684;&#x8D44;&#x6E90;&#x521B;&#x5EFA;&#x4E00;&#x4E2A; <code>RequestMatcher</code>&#x3002;</p>
<p><a id="boot-features-security-webflux"></a></p>
<h3 id="292&#x3001;webflux-&#x5B89;&#x5168;">29.2&#x3001;WebFlux &#x5B89;&#x5168;</h3>
<p>&#x4E0E; Spring MVC &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7C7B;&#x4F3C;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6DFB;&#x52A0; <code>spring-boot-starter-security</code> &#x4F9D;&#x8D56;&#x6765;&#x4FDD;&#x62A4; WebFlux &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;&#x9ED8;&#x8BA4;&#x7684;&#x5B89;&#x5168;&#x914D;&#x7F6E;&#x5728; <code>ReactiveSecurityAutoConfiguration</code> &#x548C; <code>UserDetailsServiceAutoConfiguration</code> &#x4E2D;&#x5B9E;&#x73B0;&#x3002;<code>ReactiveSecurityAutoConfiguration</code> &#x5BFC;&#x5165;&#x7528;&#x4E8E; Web &#x5B89;&#x5168;&#x7684; <code>WebFluxSecurityConfiguration</code>&#xFF0C;<code>UserDetailsServiceAutoConfiguration</code> &#x914D;&#x7F6E;&#x8EAB;&#x4EFD;&#x9A8C;&#x8BC1;&#xFF0C;&#x8FD9;&#x540C;&#x6837;&#x9002;&#x7528;&#x4E8E;&#x975E; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;&#x8981;&#x5B8C;&#x5168;&#x5173;&#x95ED;&#x9ED8;&#x8BA4;&#x7684; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5B89;&#x5168;&#x914D;&#x7F6E;&#xFF0C;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0; <code>WebFilterChainProxy</code> &#x7C7B;&#x578B;&#x7684; bean&#xFF08;&#x8FD9;&#x6837;&#x505A;&#x4E0D;&#x4F1A;&#x7981;&#x7528; <code>UserDetailsS&#x200B;&#x200B;ervice</code> &#x914D;&#x7F6E;&#x6216; Actuator &#x7684;&#x5B89;&#x5168;&#x4FDD;&#x62A4;&#xFF09;&#x3002;</p>
<p>&#x8981;&#x540C;&#x65F6;&#x5173;&#x95ED; <code>UserDetailsS&#x200B;&#x200B;ervice</code> &#x914D;&#x7F6E;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0; <code>ReactiveUserDetailsService</code> &#x6216; <code>ReactiveAuthenticationManager</code> &#x7C7B;&#x578B;&#x7684; bean&#x3002;</p>
<p>&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6DFB;&#x52A0;&#x81EA;&#x5B9A;&#x4E49; <code>SecurityWebFilterChain</code> &#x6765;&#x91CD;&#x5199;&#x8BBF;&#x95EE;&#x89C4;&#x5219;&#x3002;Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x4FBF;&#x6377;&#x65B9;&#x6CD5;&#xFF0C;&#x53EF;&#x7528;&#x4E8E;&#x91CD;&#x5199; actuator &#x7AEF;&#x70B9;&#x548C;&#x9759;&#x6001;&#x8D44;&#x6E90;&#x7684;&#x8BBF;&#x95EE;&#x89C4;&#x5219;&#x3002;<code>EndpointRequest</code> &#x53EF;&#x7528;&#x4E8E;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x57FA;&#x4E8E; <code>management.endpoints.web.base-path</code> &#x5C5E;&#x6027;&#x7684; <code>ServerWebExchangeMatcher</code>&#x3002;</p>
<p><code>PathRequest</code> &#x53EF;&#x7528;&#x4E8E;&#x4E3A;&#x5E38;&#x7528;&#x4F4D;&#x7F6E;&#x4E2D;&#x7684;&#x8D44;&#x6E90;&#x521B;&#x5EFA;&#x4E00;&#x4E2A; <code>ServerWebExchangeMatcher</code>&#x3002;</p>
<p>&#x4F8B;&#x5982;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6DFB;&#x52A0;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;&#x6765;&#x81EA;&#x5B9A;&#x4E49;&#x5B89;&#x5168;&#x914D;&#x7F6E;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">SecurityWebFilterChain</span> <span class="token function">springSecurityFilterChain</span><span class="token punctuation">(</span><span class="token class-name">ServerHttpSecurity</span> http<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> http
        <span class="token punctuation">.</span><span class="token function">authorizeExchange</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">matchers</span><span class="token punctuation">(</span><span class="token class-name">PathRequest</span><span class="token punctuation">.</span><span class="token function">toStaticResources</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">atCommonLocations</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">permitAll</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">pathMatchers</span><span class="token punctuation">(</span><span class="token string">&quot;/foo&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;/bar&quot;</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">authenticated</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">and</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">formLogin</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">and</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-security-oauth2"></a></p>
<h3 id="293&#x3001;oauth2">29.3&#x3001;OAuth2</h3>
<p><a href="https://oauth.net/2/" target="_blank">OAuth2</a> &#x662F; Spring &#x652F;&#x6301;&#x7684;&#x4E00;&#x79CD;&#x5E7F;&#x6CDB;&#x4F7F;&#x7528;&#x7684;&#x6388;&#x6743;&#x6846;&#x67B6;&#x3002;</p>
<p><a id="boot-features-security-oauth2-client"></a></p>
<h4 id="2931&#x3001;&#x5BA2;&#x6237;&#x7AEF;">29.3.1&#x3001;&#x5BA2;&#x6237;&#x7AEF;</h4>
<p>&#x5982;&#x679C;&#x60A8;&#x7684; classpath &#x4E0A;&#x6709; <code>spring-security-oauth2-client</code>&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5229;&#x7528;&#x4E00;&#x4E9B;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x6765;&#x8F7B;&#x677E;&#x8BBE;&#x7F6E; <code>OAuth2/Open ID Connect &#x5BA2;&#x6237;&#x7AEF;&#x3002;&#x8BE5;&#x914D;&#x7F6E;&#x4F7F;&#x7528;</code>OAuth2ClientProperties` &#x7684;&#x5C5E;&#x6027;&#x3002;&#x76F8;&#x540C;&#x7684;&#x5C5E;&#x6027;&#x9002;&#x7528;&#x4E8E; servlet &#x548C;&#x54CD;&#x5E94;&#x5F0F;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;</p>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>spring.security.oauth2.client</code> &#x524D;&#x7F00;&#x4E0B;&#x6CE8;&#x518C;&#x591A;&#x4E2A; OAuth2 &#x5BA2;&#x6237;&#x7AEF;&#x548C;&#x63D0;&#x4F9B;&#x8005;&#xFF08;provider&#xFF09;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.security.oauth2.client.registration.my-client-1.client-id</span><span class="token attr-value"><span class="token punctuation">=</span>abcd</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-1.client-secret</span><span class="token attr-value"><span class="token punctuation">=</span>password</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-1.client-name</span><span class="token attr-value"><span class="token punctuation">=</span>Client for user scope</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-1.provider</span><span class="token attr-value"><span class="token punctuation">=</span>my-oauth-provider</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-1.scope</span><span class="token attr-value"><span class="token punctuation">=</span>user</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-1.redirect-uri-template</span><span class="token attr-value"><span class="token punctuation">=</span>http://my-redirect-uri.com</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-1.client-authentication-method</span><span class="token attr-value"><span class="token punctuation">=</span>basic</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-1.authorization-grant-type</span><span class="token attr-value"><span class="token punctuation">=</span>authorization_code</span>

<span class="token constant">spring.security.oauth2.client.registration.my-client-2.client-id</span><span class="token attr-value"><span class="token punctuation">=</span>abcd</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-2.client-secret</span><span class="token attr-value"><span class="token punctuation">=</span>password</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-2.client-name</span><span class="token attr-value"><span class="token punctuation">=</span>Client for email scope</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-2.provider</span><span class="token attr-value"><span class="token punctuation">=</span>my-oauth-provider</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-2.scope</span><span class="token attr-value"><span class="token punctuation">=</span>email</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-2.redirect-uri-template</span><span class="token attr-value"><span class="token punctuation">=</span>http://my-redirect-uri.com</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-2.client-authentication-method</span><span class="token attr-value"><span class="token punctuation">=</span>basic</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client-2.authorization-grant-type</span><span class="token attr-value"><span class="token punctuation">=</span>authorization_code</span>

<span class="token constant">spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri</span><span class="token attr-value"><span class="token punctuation">=</span>http://my-auth-server/oauth/authorize</span>
<span class="token constant">spring.security.oauth2.client.provider.my-oauth-provider.token-uri</span><span class="token attr-value"><span class="token punctuation">=</span>http://my-auth-server/oauth/token</span>
<span class="token constant">spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri</span><span class="token attr-value"><span class="token punctuation">=</span>http://my-auth-server/userinfo</span>
<span class="token constant">spring.security.oauth2.client.provider.my-oauth-provider.user-info-authentication-method</span><span class="token attr-value"><span class="token punctuation">=</span>header</span>
<span class="token constant">spring.security.oauth2.client.provider.my-oauth-provider.jwk-set-uri</span><span class="token attr-value"><span class="token punctuation">=</span>http://my-auth-server/token_keys</span>
<span class="token constant">spring.security.oauth2.client.provider.my-oauth-provider.user-name-attribute</span><span class="token attr-value"><span class="token punctuation">=</span>name</span>
</code></pre>
<p>&#x5BF9;&#x4E8E;&#x652F;&#x6301; <a href="https://openid.net/specs/openid-connect-discovery-1_0.html" target="_blank">OpenID Connect &#x53D1;&#x73B0;</a>&#x7684; OpenID Connect &#x63D0;&#x4F9B;&#x8005;&#xFF0C;&#x53EF;&#x4EE5;&#x8FDB;&#x4E00;&#x6B65;&#x7B80;&#x5316;&#x914D;&#x7F6E;&#x3002;&#x9700;&#x8981;&#x4F7F;&#x7528; <code>issuer-uri</code> &#x914D;&#x7F6E;&#x63D0;&#x4F9B;&#x8005;&#xFF0C;<code>issuer-uri</code> &#x662F;&#x5176; Issuer Identifier &#x7684; URI&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5982;&#x679C;&#x63D0;&#x4F9B;&#x7684; <code>issuer-uri</code> &#x662F; &#x201C;<a href="https://example.com&#x201D;&#xFF0C;&#x5219;&#x5C06;&#x5BF9;" target="_blank">https://example.com&#x201D;&#xFF0C;&#x5219;&#x5C06;&#x5BF9;</a> &#x201C;<a href="https://example.com/.well-known/openid-configuration&#x201D;" target="_blank">https://example.com/.well-known/openid-configuration&#x201D;</a> &#x53D1;&#x8D77;&#x4E00;&#x4E2A; <code>OpenID Provider Configuration Request</code>&#x3002;&#x671F;&#x671B;&#x7ED3;&#x679C;&#x662F;&#x4E00;&#x4E2A; <code>OpenID Provider Configuration Response</code>&#x3002;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x4F7F;&#x7528; <code>issuer-uri</code> &#x914D;&#x7F6E;&#x4E00;&#x4E2A; OpenID Connect Provider&#xFF1A;</p>
<pre class="language-"><code>spring.security.oauth2.client.provider.oidc-provider.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/
</code></pre><p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Spring Security &#x7684; <code>OAuth2LoginAuthenticationFilter</code> &#x4EC5;&#x5904;&#x7406;&#x4E0E; <code>/login/oauth2/code/*</code> &#x76F8;&#x5339;&#x914D;&#x7684; URL&#x3002;&#x5982;&#x679C;&#x8981;&#x81EA;&#x5B9A;&#x4E49; <code>redirect-uri</code> &#x4EE5;&#x4F7F;&#x7528;&#x5176;&#x4ED6;&#x5339;&#x914D;&#x6A21;&#x5F0F;&#xFF0C;&#x5219;&#x9700;&#x8981;&#x63D0;&#x4F9B;&#x914D;&#x7F6E;&#x4EE5;&#x5904;&#x7406;&#x8BE5;&#x81EA;&#x5B9A;&#x4E49;&#x6A21;&#x5F0F;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5BF9;&#x4E8E; servlet &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0;&#x7C7B;&#x4F3C;&#x4E8E;&#x4EE5;&#x4E0B; <code>WebSecurityConfigurerAdapter</code>&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">OAuth2LoginSecurityConfig</span> <span class="token keyword">extends</span> <span class="token class-name">WebSecurityConfigurerAdapter</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">configure</span><span class="token punctuation">(</span><span class="token class-name">HttpSecurity</span> http<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">Exception</span> <span class="token punctuation">{</span>
        http
            <span class="token punctuation">.</span><span class="token function">authorizeRequests</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">anyRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">authenticated</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">and</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">oauth2Login</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">redirectionEndpoint</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                    <span class="token punctuation">.</span><span class="token function">baseUri</span><span class="token punctuation">(</span><span class="token string">&quot;/custom-callback&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-security-oauth2-common-providers"></a></p>
<p><strong>OAuth2 &#x5BA2;&#x6237;&#x7AEF;&#x6CE8;&#x518C;&#x5E38;&#x89C1;&#x7684;&#x63D0;&#x4F9B;&#x8005;</strong></p>
<p>&#x5BF9;&#x4E8E;&#x5E38;&#x89C1;&#x7684; OAuth2 &#x548C; OpenID &#x63D0;&#x4F9B;&#x8005;&#xFF08;provider&#xFF09;&#xFF0C;&#x5305;&#x62EC; Google&#x3001;Github&#x3001;Facebook &#x548C; Okta&#xFF0C;&#x6211;&#x4EEC;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x7EC4;&#x63D0;&#x4F9B;&#x8005;&#x9ED8;&#x8BA4;&#x8BBE;&#x7F6E;&#xFF08;&#x5206;&#x522B;&#x662F; <code>google</code>&#x3001;<code>github</code>&#x3001;<code>facebook</code> &#x548C; <code>okta</code>&#xFF09;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x4E0D;&#x9700;&#x8981;&#x81EA;&#x5B9A;&#x4E49;&#x8FD9;&#x4E9B;&#x63D0;&#x4F9B;&#x8005;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5C06; <code>provider</code> &#x5C5E;&#x6027;&#x8BBE;&#x7F6E;&#x4E3A;&#x60A8;&#x9700;&#x8981;&#x63A8;&#x65AD;&#x9ED8;&#x8BA4;&#x503C;&#x7684;&#x5C5E;&#x6027;&#x3002;&#x6B64;&#x5916;&#xFF0C;&#x5982;&#x679C;&#x5BA2;&#x6237;&#x7AEF;&#x6CE8;&#x518C;&#x7684; key &#x4E0E;&#x9ED8;&#x8BA4;&#x652F;&#x6301;&#x7684;&#x63D0;&#x4F9B;&#x8005;&#x5339;&#x914D;&#xFF0C;&#x5219; Spring Boot &#x4E5F;&#x4F1A;&#x63A8;&#x65AD;&#x51FA;&#x6765;&#x3002;</p>
<p>&#x6362;&#x800C;&#x8A00;&#x4E4B;&#xFF0C;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x4E2D;&#x7684;&#x4E24;&#x4E2A;&#x914D;&#x7F6E;&#x4F7F;&#x7528;&#x4E86; Google &#x63D0;&#x4F9B;&#x8005;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.security.oauth2.client.registration.my-client.client-id</span><span class="token attr-value"><span class="token punctuation">=</span>abcd</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client.client-secret</span><span class="token attr-value"><span class="token punctuation">=</span>password</span>
<span class="token constant">spring.security.oauth2.client.registration.my-client.provider</span><span class="token attr-value"><span class="token punctuation">=</span>google</span>

<span class="token constant">spring.security.oauth2.client.registration.google.client-id</span><span class="token attr-value"><span class="token punctuation">=</span>abcd</span>
<span class="token constant">spring.security.oauth2.client.registration.google.client-secret</span><span class="token attr-value"><span class="token punctuation">=</span>password</span>
</code></pre>
<p><a id="boot-features-security-oauth2-server"></a></p>
<h4 id="2932&#x3001;&#x8D44;&#x6E90;&#x670D;&#x52A1;&#x5668;">29.3.2&#x3001;&#x8D44;&#x6E90;&#x670D;&#x52A1;&#x5668;</h4>
<p>&#x5982;&#x679C;&#x5728; classpath &#x4E0A;&#x6709; <code>spring-security-oauth2-resource-server</code>&#xFF0C;&#x53EA;&#x8981;&#x6307;&#x5B9A;&#x4E86; JWK Set URI &#x6216; OIDC Issuer URI&#xFF0C;Spring Boot &#x5C31;&#x53EF;&#x4EE5;&#x8BBE;&#x7F6E; OAuth2 &#x8D44;&#x6E90;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.security.oauth2.resourceserver.jwt.jwk-set-uri</span><span class="token attr-value"><span class="token punctuation">=</span>https://example.com/oauth2/default/v1/keys</span>
</code></pre>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.security.oauth2.resourceserver.jwt.issuer-uri</span><span class="token attr-value"><span class="token punctuation">=</span>https://dev-123456.oktapreview.com/oauth2/default/</span>
</code></pre>
<p>&#x76F8;&#x540C;&#x7684;&#x5C5E;&#x6027;&#x9002;&#x7528;&#x4E8E; servlet &#x548C;&#x54CD;&#x5E94;&#x5F0F;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;</p>
<p>&#x6216;&#x8005;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4E3A; servlet &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5B9A;&#x4E49;&#x81EA;&#x5DF1;&#x7684; <code>JwtDecoder</code> bean&#xFF0C;&#x6216;&#x4E3A;&#x54CD;&#x5E94;&#x5F0F;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5B9A;&#x4E49; <code>ReactiveJwtDecoder</code>&#x3002;</p>
<p><a id="_authorization_server"></a></p>
<h4 id="2933&#x3001;&#x6388;&#x6743;&#x670D;&#x52A1;&#x5668;">29.3.3&#x3001;&#x6388;&#x6743;&#x670D;&#x52A1;&#x5668;</h4>
<p>&#x76EE;&#x524D;&#xFF0C;Spring Security &#x6CA1;&#x6709;&#x63D0;&#x4F9B; OAuth 2.0 &#x6388;&#x6743;&#x670D;&#x52A1;&#x5668;&#x5B9E;&#x73B0;&#x3002;&#x4F46;&#x6B64;&#x529F;&#x80FD;&#x53EF;&#x4ECE; <a href="https://projects.spring.io/spring-security-oauth/" target="_blank">Spring Security OAuth</a> &#x9879;&#x76EE;&#x83B7;&#x5F97;&#xFF0C;&#x8BE5;&#x9879;&#x76EE;&#x6700;&#x7EC8;&#x4F1A;&#x88AB; Spring Security &#x6240;&#x53D6;&#x4EE3;&#x3002;&#x5728;&#x6B64;&#x4E4B;&#x524D;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring-security-oauth2-autoconfigure</code> &#x6A21;&#x5757;&#x8F7B;&#x677E;&#x8BBE;&#x7F6E; OAuth 2.0 &#x6388;&#x6743;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x8BF7;&#x53C2;&#x9605;&#x5176;<a href="https://docs.spring.io/spring-security-oauth2-boot" target="_blank">&#x6587;&#x6863;</a>&#x4EE5;&#x83B7;&#x53D6;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#x3002;</p>
<p><a id="boot-features-security-actuator"></a></p>
<h3 id="294&#x3001;actuator-&#x5B89;&#x5168;">29.4&#x3001;Actuator &#x5B89;&#x5168;</h3>
<p>&#x51FA;&#x4E8E;&#x5B89;&#x5168;&#x8003;&#x8651;&#xFF0C;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#x7981;&#x7528;&#x9664; <code>/health</code> &#x548C; <code>/info</code> &#x4E4B;&#x5916;&#x7684;&#x6240;&#x6709; actuator&#x3002;&#x53EF;&#x7528; <code>management.endpoints.web.exposure.include</code> &#x5C5E;&#x6027;&#x542F;&#x7528; actuator&#x3002;</p>
<p>&#x5982;&#x679C; Spring Security &#x4F4D;&#x4E8E; classpath &#x4E0A;&#x4E14;&#x6CA1;&#x6709;&#x5176;&#x4ED6; <code>WebSecurityConfigurerAdapter</code>&#xFF0C;&#x5219;&#x9664;&#x4E86; <code>/health</code> &#x548C; <code>/info</code> &#x4E4B;&#x5916;&#x7684;&#x6240;&#x6709; actuator &#x90FD;&#x7531; Spring Boot &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4FDD;&#x62A4;&#x3002;&#x5982;&#x679C;&#x60A8;&#x5B9A;&#x4E49;&#x4E86;&#x81EA;&#x5B9A;&#x4E49; <code>WebSecurityConfigurerAdapter</code>&#xFF0C;&#x5219; Spring Boot &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x5C06;&#x4E0D;&#x518D;&#x751F;&#x6548;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5B8C;&#x5168;&#x63A7;&#x5236; actuator &#x7684;&#x8BBF;&#x95EE;&#x89C4;&#x5219;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5728;&#x8BBE;&#x7F6E; <code>management.endpoints.web.exposure.include</code> &#x4E4B;&#x524D;&#xFF0C;&#x8BF7;&#x786E;&#x4FDD;&#x66B4;&#x9732;&#x7684; actuator &#x6CA1;&#x6709;&#x5305;&#x542B;&#x654F;&#x611F;&#x4FE1;&#x606F;&#x548C; <code>/</code> &#x6216;&#x88AB;&#x9632;&#x706B;&#x5899;&#x4FDD;&#x62A4;&#x4EA6;&#x6216;&#x53D7; Spring Security &#x4E4B;&#x7C7B;&#x7684;&#x4FDD;&#x62A4;&#x3002;</p>
</blockquote>
<p><a id="boot-features-security-csrf"></a></p>
<h4 id="2941&#x3001;&#x8DE8;&#x7AD9;&#x8BF7;&#x6C42;&#x4F2A;&#x9020;&#x4FDD;&#x62A4;">29.4.1&#x3001;&#x8DE8;&#x7AD9;&#x8BF7;&#x6C42;&#x4F2A;&#x9020;&#x4FDD;&#x62A4;</h4>
<p>&#x7531;&#x4E8E; Spring Boot &#x4F9D;&#x8D56; Spring Security &#x7684;&#x9ED8;&#x8BA4;&#x503C;&#x914D;&#x7F6E;&#xFF0C;&#x56E0;&#x6B64;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#x4F1A;&#x542F;&#x7528; CSRF &#x4FDD;&#x62A4;&#x3002;&#x8FD9;&#x610F;&#x5473;&#x7740;&#x5F53;&#x4F7F;&#x7528;&#x9ED8;&#x8BA4;&#x5B89;&#x5168;&#x914D;&#x7F6E;&#x65F6;&#xFF0C;&#x9700;&#x8981; <code>POST</code>&#xFF08;shutdown &#x548C; loggers &#x7AEF;&#x70B9;&#xFF09;&#x3001;<code>PUT</code> &#x6216; <code>DELETE</code> &#x7684; actuator &#x7AEF;&#x70B9;&#x5C06;&#x8FD4;&#x56DE; 403 &#x7981;&#x6B62;&#x8BBF;&#x95EE;&#x9519;&#x8BEF;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x6211;&#x4EEC;&#x5EFA;&#x8BAE;&#x4EC5;&#x5728;&#x521B;&#x5EFA;&#x975E;&#x6D4F;&#x89C8;&#x5668;&#x5BA2;&#x6237;&#x7AEF;&#x4F7F;&#x7528;&#x7684;&#x670D;&#x52A1;&#x65F6;&#x624D;&#x5B8C;&#x5168;&#x7981;&#x7528; CSRF &#x4FDD;&#x62A4;&#x3002;</p>
</blockquote>
<p>&#x6709;&#x5173; CSRF &#x4FDD;&#x62A4;&#x7684;&#x5176;&#x4ED6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://docs.spring.io/spring-security/site/docs/5.1.2.RELEASE/reference/htmlsingle#csrf" target="_blank">Spring Security &#x53C2;&#x8003;&#x6307;&#x5357;</a>&#x3002;</p>
<p><a id="boot-features-sql"></a></p>
<h2 id="30&#x3001;&#x4F7F;&#x7528;-sql-&#x6570;&#x636E;&#x5E93;">30&#x3001;&#x4F7F;&#x7528; SQL &#x6570;&#x636E;&#x5E93;</h2>
<p><a href="https://projects.spring.io/spring-framework/" target="_blank">Spring Framework</a> &#x4E3A; SQL &#x6570;&#x636E;&#x5E93;&#x63D0;&#x4F9B;&#x4E86;&#x5E7F;&#x6CDB;&#x7684;&#x652F;&#x6301;&#x3002;&#x4ECE;&#x76F4;&#x63A5;&#x4F7F;&#x7528; <code>JdbcTemplate</code> &#x8FDB;&#x884C; JDBC &#x8BBF;&#x95EE;&#x5230;&#x5B8C;&#x5168;&#x7684;<strong>&#x5BF9;&#x8C61;&#x5173;&#x7CFB;&#x6620;&#x5C04;</strong>&#xFF08;object relational mapping&#xFF09;&#x6280;&#x672F;&#xFF0C;&#x6BD4;&#x5982; Hibernate&#x3002;<a href="https://projects.spring.io/spring-data/" target="_blank">Spring Data</a> &#x63D0;&#x4F9B;&#x4E86;&#x66F4;&#x591A;&#x7EA7;&#x522B;&#x7684;&#x529F;&#x80FD;&#xFF0C;&#x76F4;&#x63A5;&#x4ECE;&#x63A5;&#x53E3;&#x521B;&#x5EFA;&#x7684; <code>Repository</code> &#x5B9E;&#x73B0;&#xFF0C;&#x5E76;&#x4F7F;&#x7528;&#x4E86;&#x7EA6;&#x5B9A;&#x4ECE;&#x65B9;&#x6CD5;&#x540D;&#x751F;&#x6210;&#x67E5;&#x8BE2;&#x3002;</p>
<p><a id="boot-features-configure-datasource"></a></p>
<h3 id="301&#x3001;&#x914D;&#x7F6E;&#x6570;&#x636E;&#x6E90;">30.1&#x3001;&#x914D;&#x7F6E;&#x6570;&#x636E;&#x6E90;</h3>
<p>Java &#x7684; <code>javax.sql.DataSource</code> &#x63A5;&#x53E3;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x4F7F;&#x7528;&#x6570;&#x636E;&#x5E93;&#x8FDE;&#x63A5;&#x7684;&#x6807;&#x51C6;&#x65B9;&#x6CD5;&#x3002;&#x901A;&#x5E38;&#xFF0C;&#x6570;&#x636E;&#x6E90;&#x4F7F;&#x7528; <code>URL</code> &#x548C;&#x4E00;&#x4E9B;&#x51ED;&#x636E;&#x4FE1;&#x606F;&#x6765;&#x5EFA;&#x7ACB;&#x6570;&#x636E;&#x5E93;&#x8FDE;&#x63A5;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x67E5;&#x770B; <a href="#howto-configure-a-datasource">How-to</a> &#x90E8;&#x5206;&#x83B7;&#x53D6;&#x66F4;&#x591A;&#x9AD8;&#x7EA7;&#x793A;&#x4F8B;&#xFF0C;&#x901A;&#x5E38;&#x60A8;&#x53EF;&#x4EE5;&#x5B8C;&#x5168;&#x63A7;&#x5236;&#x6570;&#x636E;&#x5E93;&#x7684;&#x914D;&#x7F6E;&#x3002;</p>
</blockquote>
<p><a id="boot-features-embedded-database-support"></a></p>
<h4 id="3011&#x3001;&#x5185;&#x5D4C;&#x6570;&#x636E;&#x5E93;&#x652F;&#x6301;">30.1.1&#x3001;&#x5185;&#x5D4C;&#x6570;&#x636E;&#x5E93;&#x652F;&#x6301;</h4>
<p>&#x4F7F;&#x7528;&#x5185;&#x5D4C;&#x5185;&#x5B58;&#x6570;&#x636E;&#x5E93;&#x6765;&#x5F00;&#x53D1;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x975E;&#x5E38;&#x65B9;&#x4FBF;&#x7684;&#x3002;&#x663E;&#x7136;&#xFF0C;&#x5185;&#x5B58;&#x6570;&#x636E;&#x5E93;&#x4E0D;&#x63D0;&#x4F9B;&#x6301;&#x4E45;&#x5B58;&#x50A8;&#x3002;&#x5728;&#x5E94;&#x7528;&#x542F;&#x52A8;&#x65F6;&#xFF0C;&#x60A8;&#x9700;&#x8981;&#x586B;&#x5145;&#x6570;&#x636E;&#x5E93;&#xFF0C;&#x5E76;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7ED3;&#x675F;&#x65F6;&#x4E22;&#x5F03;&#x6570;&#x636E;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p><strong>How-to</strong> &#x90E8;&#x5206;&#x5305;&#x542B;&#x4E86;<a href="#howto-database-initialization">&#x5982;&#x4F55;&#x521D;&#x59CB;&#x5316;&#x6570;&#x636E;&#x5E93;</a>&#x65B9;&#x9762;&#x7684;&#x5185;&#x5BB9;&#x3002;</p>
</blockquote>
<p>Spring Boot &#x53EF;&#x4EE5;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x5185;&#x5D4C; <a href="http://www.h2database.com/" target="_blank">H2</a>&#x3001;<a href="http://hsqldb.org/" target="_blank">HSQL</a> &#x548C; <a href="https://db.apache.org/derby/" target="_blank">Derby</a> &#x6570;&#x636E;&#x5E93;&#x3002;&#x60A8;&#x4E0D;&#x9700;&#x8981;&#x63D0;&#x4F9B;&#x4EFB;&#x4F55;&#x8FDE;&#x63A5; URL&#xFF0C;&#x53EA;&#x9700;&#x4E3A;&#x60A8;&#x60F3;&#x8981;&#x4F7F;&#x7528;&#x7684;&#x5185;&#x5D4C;&#x6570;&#x636E;&#x5E93;&#x5F15;&#x5165;&#x7279;&#x5B9A;&#x7684;&#x6784;&#x5EFA;&#x4F9D;&#x8D56;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x5728;&#x6D4B;&#x8BD5;&#x4E2D;&#x4F7F;&#x7528;&#x6B64;&#x529F;&#x80FD;&#xFF0C;&#x60A8;&#x53EF;&#x80FD;&#x4F1A;&#x6CE8;&#x610F;&#x5230;&#xFF0C;&#x65E0;&#x8BBA;&#x4F7F;&#x7528;&#x4E86;&#x591A;&#x5C11;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E0A;&#x4E0B;&#x6587;&#xFF0C;&#x6574;&#x4E2A;&#x6D4B;&#x8BD5;&#x5957;&#x4EF6;&#x90FD;&#x4F1A;&#x91CD;&#x590D;&#x4F7F;&#x7528;&#x76F8;&#x540C;&#x7684;&#x6570;&#x636E;&#x5E93;&#x3002;&#x5982;&#x679C;&#x60A8;&#x60F3;&#x786E;&#x4FDD;&#x6BCF;&#x4E2A;&#x4E0A;&#x4E0B;&#x6587;&#x90FD;&#x6709;&#x4E00;&#x4E2A;&#x5355;&#x72EC;&#x7684;&#x5185;&#x5D4C;&#x6570;&#x636E;&#x5E93;&#xFF0C;&#x5219;&#x5E94;&#x8BE5;&#x5C06; <code>spring.datasource.generate-unique-name</code> &#x8BBE;&#x7F6E;&#x4E3A; <code>true</code>&#x3002;</p>
</blockquote>
<p>&#x4EE5;&#x4E0B;&#x662F; POM &#x4F9D;&#x8D56;&#x793A;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-starter-data-jpa<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.hsqldb<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>hsqldb<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>scope</span><span class="token punctuation">&gt;</span></span>runtime<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>scope</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x8981;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x5185;&#x5D4C;&#x6570;&#x636E;&#x5E93;&#xFF0C;&#x60A8;&#x9700;&#x8981;&#x4E00;&#x4E2A; <code>spring-jdbc</code> &#x4F9D;&#x8D56;&#x3002;&#x5728;&#x8FD9;&#x4E2A;&#x4F8B;&#x5B50;&#x4E2D;&#xFF0C;&#x5B83;&#x662F;&#x901A;&#x8FC7; <code>spring-boot-starter-data-jpa</code> &#x5F15;&#x5165;&#x3002;</p>
</blockquote>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x51FA;&#x4E8E;&#x67D0;&#x4E9B;&#x539F;&#x56E0;&#xFF0C;&#x60A8;&#x9700;&#x8981;&#x914D;&#x7F6E;&#x5185;&#x5D4C;&#x6570;&#x636E;&#x5E93;&#x7684;&#x8FDE;&#x63A5; URL&#xFF0C;&#x5219;&#x5E94;&#x6CE8;&#x610F;&#x786E;&#x4FDD;&#x7981;&#x7528;&#x6570;&#x636E;&#x5E93;&#x7684;&#x81EA;&#x52A8;&#x5173;&#x95ED;&#x529F;&#x80FD;&#x3002;&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528; H2&#xFF0C;&#x5219;&#x5E94;&#x8BE5;&#x4F7F;&#x7528; <code>DB_CLOSE_ON_EXIT=FALSE</code> &#x6765;&#x8BBE;&#x7F6E;&#x3002;&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528; <code>HSQLDB</code>&#xFF0C;&#x5219;&#x786E;&#x4FDD;&#x4E0D;&#x4F7F;&#x7528; <code>shutdown=true</code>&#x3002;&#x7981;&#x7528;&#x6570;&#x636E;&#x5E93;&#x7684;&#x81EA;&#x52A8;&#x5173;&#x95ED;&#x529F;&#x80FD;&#x5141;&#x8BB8; Spring Boot &#x63A7;&#x5236;&#x6570;&#x636E;&#x5E93;&#x4F55;&#x65F6;&#x5173;&#x95ED;&#xFF0C;&#x4ECE;&#x800C;&#x786E;&#x4FDD;&#x4E00;&#x65E6;&#x4E0D;&#x518D;&#x9700;&#x8981;&#x8BBF;&#x95EE;&#x6570;&#x636E;&#x5E93;&#x65F6;&#x5C31;&#x89E6;&#x53D1;&#x3002;</p>
</blockquote>
<p><a id="boot-features-connect-to-production-database"></a></p>
<h4 id="3012&#x3001;&#x8FDE;&#x63A5;&#x751F;&#x4EA7;&#x6570;&#x636E;&#x5E93;">30.1.2&#x3001;&#x8FDE;&#x63A5;&#x751F;&#x4EA7;&#x6570;&#x636E;&#x5E93;</h4>
<p>&#x751F;&#x4EA7;&#x6570;&#x636E;&#x5E93;&#x8FDE;&#x63A5;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4F7F;&#x7528; <code>DataSource</code> &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;Spring Boot &#x4F7F;&#x7528;&#x4EE5;&#x4E0B;&#x7B97;&#x6CD5;&#x6765;&#x9009;&#x62E9;&#x4E00;&#x4E2A;&#x7279;&#x5B9A;&#x7684;&#x5B9E;&#x73B0;&#xFF1A;</p>
<ul>
<li>&#x51FA;&#x4E8E;&#x6027;&#x80FD;&#x548C;&#x5E76;&#x53D1;&#x6027;&#x7684;&#x8003;&#x8651;&#xFF0C;&#x6211;&#x4EEC;&#x66F4;&#x559C;&#x6B22; <a href="https://github.com/brettwooldridge/HikariCP" target="_blank">HikariCP</a> &#x8FDE;&#x63A5;&#x6C60;&#x3002;&#x5982;&#x679C; HikariCP &#x53EF;&#x7528;&#xFF0C;&#x6211;&#x4EEC;&#x603B;&#x662F;&#x9009;&#x62E9;&#x5B83;&#x3002;</li>
<li>&#x5426;&#x5219;&#xFF0C;&#x5982;&#x679C; Tomcat &#x6C60; <code>DataSource</code> &#x53EF;&#x7528;&#xFF0C;&#x6211;&#x4EEC;&#x5C06;&#x4F7F;&#x7528;&#x5B83;&#x3002;</li>
<li>&#x5982;&#x679C; HikariCP &#x548C; Tomcat &#x6C60;&#x6570;&#x636E;&#x6E90;&#x4E0D;&#x53EF;&#x7528;&#xFF0C;&#x4F46; <a href="https://commons.apache.org/proper/commons-dbcp/" target="_blank">Commons DBCP</a> &#x53EF;&#x7528;&#xFF0C;&#x6211;&#x4EEC;&#x5C06;&#x4F7F;&#x7528;&#x5B83;&#x3002;</li>
</ul>
<p>&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528;&#x4E86; <code>spring-boot-starter-jdbc</code> &#x6216;&#x8005; <code>spring-boot-starter-data-jpa</code> starter&#xFF0C;&#x60A8;&#x5C06;&#x81EA;&#x52A8;&#x5F97;&#x5230; <code>HikariCP</code> &#x4F9D;&#x8D56;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x60A8;&#x5B8C;&#x5168;&#x53EF;&#x4EE5;&#x7ED5;&#x8FC7;&#x8BE5;&#x7B97;&#x6CD5;&#xFF0C;&#x5E76;&#x901A;&#x8FC7; <code>spring.datasource.type</code> &#x5C5E;&#x6027;&#x6307;&#x5B9A;&#x8981;&#x4F7F;&#x7528;&#x7684;&#x8FDE;&#x63A5;&#x6C60;&#x3002;&#x5982;&#x679C;&#x60A8;&#x5728; Tomcat &#x5BB9;&#x5668;&#x4E2D;&#x8FD0;&#x884C;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;&#x9ED8;&#x8BA4;&#x63D0;&#x4F9B; <code>tomcat-jdbc</code>&#xFF0C;&#x8FD9;&#x70B9;&#x5C24;&#x5176;&#x91CD;&#x8981;&#x3002;</p>
</blockquote>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x53EF;&#x4EE5;&#x624B;&#x52A8;&#x914D;&#x7F6E;&#x5176;&#x4ED6;&#x8FDE;&#x63A5;&#x6C60;&#x3002;&#x5982;&#x679C;&#x60A8;&#x5B9A;&#x4E49;&#x4E86;&#x81EA;&#x5DF1;&#x7684; <code>DataSource</code> bean&#xFF0C;&#x5219;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x5C06;&#x4E0D;&#x4F1A;&#x89E6;&#x53D1;&#x3002;</p>
</blockquote>
<p>&#x6570;&#x636E;&#x6E90;&#x914D;&#x7F6E;&#x7531; <code>spring.datasource.*</code> &#x4E2D;&#x7684;&#x5916;&#x90E8;&#x5C5E;&#x6027;&#x6240;&#x63A7;&#x5236;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>application.properties</code> &#x4E2D;&#x58F0;&#x660E;&#x4EE5;&#x4E0B;&#x90E8;&#x5206;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.datasource.url</span><span class="token attr-value"><span class="token punctuation">=</span>jdbc:mysql://localhost/test</span>
<span class="token constant">spring.datasource.username</span><span class="token attr-value"><span class="token punctuation">=</span>dbuser</span>
<span class="token constant">spring.datasource.password</span><span class="token attr-value"><span class="token punctuation">=</span>dbpass</span>
<span class="token constant">spring.datasource.driver-class-name</span><span class="token attr-value"><span class="token punctuation">=</span>com.mysql.jdbc.Driver</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x60A8;&#x81F3;&#x5C11;&#x5E94;&#x8BE5;&#x4F7F;&#x7528; <code>spring.datasource.url</code> &#x5C5E;&#x6027;&#x6765;&#x6307;&#x5B9A; URL&#xFF0C;&#x5426;&#x5219; Spring Boot &#x5C06;&#x5C1D;&#x8BD5;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x5185;&#x5D4C;&#x6570;&#x636E;&#x5E93;&#x3002;</p>
</blockquote>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x901A;&#x5E38;&#x60A8;&#x4E0D;&#x9700;&#x8981;&#x6307;&#x5B9A; <code>driver-class-name</code>&#xFF0C;&#x56E0;&#x4E3A; Spring boot &#x53EF;&#x4EE5;&#x4ECE; <code>url</code> &#x63A8;&#x5BFC;&#x51FA;&#x5927;&#x591A;&#x6570;&#x6570;&#x636E;&#x5E93;&#x3002;</p>
</blockquote>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5BF9;&#x4E8E;&#x8981;&#x521B;&#x5EFA;&#x7684;&#x6C60; <code>DataSource</code>&#xFF0C;&#x6211;&#x4EEC;&#x9700;&#x8981;&#x80FD;&#x591F;&#x9A8C;&#x8BC1;&#x6709;&#x6548;&#x7684; <code>Driver</code> &#x7C7B;&#x662F;&#x5426;&#x53EF;&#x7528;&#xFF0C;&#x56E0;&#x6B64;&#x6211;&#x4EEC;&#x5728;&#x4F7F;&#x7528;&#x4E4B;&#x524D;&#x8FDB;&#x884C;&#x68C0;&#x67E5;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x8BBE;&#x7F6E;&#x4E86; <code>spring.datasource.driver-class-name=com.mysql.jdbc.Driver</code>&#xFF0C;&#x90A3;&#x4E48;&#x8BE5;&#x7C7B;&#x5FC5;&#x987B;&#x53EF;&#x52A0;&#x8F7D;&#x3002;</p>
</blockquote>
<p>&#x6709;&#x5173;&#x66F4;&#x591A;&#x652F;&#x6301;&#x9009;&#x9879;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceProperties.java" target="_blank">DataSourceProperties</a>&#x3002;&#x8FD9;&#x4E9B;&#x90FD;&#x662F;&#x6807;&#x51C6;&#x9009;&#x9879;&#xFF0C;&#x4E0E;&#x5B9E;&#x9645;&#x7684;&#x5B9E;&#x73B0;&#x65E0;&#x5173;&#x3002;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x5404;&#x81EA;&#x7684;&#x524D;&#x7F00;&#xFF08;<code>spring.datasource.hikari.*</code>&#x3001;<code>spring.datasource.tomcat.*</code> &#x548C; <code>spring.datasource.dbcp2.*</code>&#xFF09;&#x5FAE;&#x8C03;&#x5B9E;&#x73B0;&#x7279;&#x5B9A;&#x7684;&#x8BBE;&#x7F6E;&#x3002;&#x8BF7;&#x53C2;&#x8003;&#x60A8;&#x73B0;&#x5728;&#x4F7F;&#x7528;&#x7684;&#x8FDE;&#x63A5;&#x6C60;&#x5B9E;&#x73B0;&#x7684;&#x6587;&#x6863;&#x6765;&#x83B7;&#x53D6;&#x66F4;&#x591A;&#x4FE1;&#x606F;&#x3002;</p>
<p>&#x4F8B;&#x5982;&#xFF0C;&#x5982;&#x679C;&#x4F60;&#x4F7F;&#x7528; <a href="https://tomcat.apache.org/tomcat-8.0-doc/jdbc-pool.html#Common_Attributes" target="_blank">Tomcat &#x8FDE;&#x63A5;&#x6C60;</a>&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x81EA;&#x5B9A;&#x4E49;&#x8BB8;&#x591A;&#x5176;&#x4ED6;&#x8BBE;&#x7F6E;&#xFF0C;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token comment"># Number of ms to wait before throwing an exception if no connection is available.</span>
<span class="token constant">spring.datasource.tomcat.max-wait</span><span class="token attr-value"><span class="token punctuation">=</span>10000</span>

<span class="token comment"># Maximum number of active connections that can be allocated from this pool at the same time.</span>
<span class="token constant">spring.datasource.tomcat.max-active</span><span class="token attr-value"><span class="token punctuation">=</span>50</span>

<span class="token comment"># Validate the connection before borrowing it from the pool.</span>
<span class="token constant">spring.datasource.tomcat.test-on-borrow</span><span class="token attr-value"><span class="token punctuation">=</span>true</span>
</code></pre>
<p><a id="boot-features-connecting-to-a-jndi-datasource"></a></p>
<h4 id="3013&#x3001;&#x8FDE;&#x63A5;-jndi-&#x6570;&#x636E;&#x6E90;">30.1.3&#x3001;&#x8FDE;&#x63A5; JNDI &#x6570;&#x636E;&#x6E90;</h4>
<p>&#x5982;&#x679C;&#x8981;&#x5C06; Spring Boot &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x90E8;&#x7F72;&#x5230;&#x5E94;&#x7528;&#x670D;&#x52A1;&#x5668;&#xFF08;Application Server&#xFF09;&#x4E0A;&#xFF0C;&#x60A8;&#x53EF;&#x80FD;&#x60F3;&#x4F7F;&#x7528;&#x5E94;&#x7528;&#x670D;&#x52A1;&#x5668;&#x7684;&#x5185;&#x7F6E;&#x529F;&#x80FD;&#x548C; JNDI &#x8BBF;&#x95EE;&#x65B9;&#x5F0F;&#x6765;&#x914D;&#x7F6E;&#x548C;&#x7BA1;&#x7406;&#x6570;&#x636E;&#x6E90;&#x3002;</p>
<p><code>spring.datasource.jndi-name</code> &#x5C5E;&#x6027;&#x53EF;&#x4F5C;&#x4E3A; <code>spring.datasource.url</code>&#x3001;<code>spring.datasource.username</code> &#x548C; <code>spring.datasource.password</code> &#x5C5E;&#x6027;&#x7684;&#x66FF;&#x4EE3;&#x65B9;&#x6CD5;&#xFF0C;&#x7528;&#x4E8E;&#x4ECE;&#x7279;&#x5B9A;&#x7684; JNDI &#x4F4D;&#x7F6E;&#x8BBF;&#x95EE; <code>DataSource</code>&#x3002;&#x4F8B;&#x5982;&#xFF0C;<code>application.properties</code> &#x4E2D;&#x7684;&#x4EE5;&#x4E0B;&#x90E8;&#x5206;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x8BBF;&#x95EE; JBoss AS &#x5B9A;&#x4E49;&#x7684; <code>DataSource</code>&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.datasource.jndi-name</span><span class="token attr-value"><span class="token punctuation">=</span>java:jboss/datasources/customers</span>
</code></pre>
<p><a id="boot-features-using-jdbc-template"></a></p>
<h3 id="302&#x3001;&#x4F7F;&#x7528;-jdbctemplate">30.2&#x3001;&#x4F7F;&#x7528; JdbcTemplate</h3>
<p>Spring &#x7684; <code>JdbcTemplate</code> &#x548C; <code>NamedParameterJdbcTemplate</code> &#x7C7B;&#x662F;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@Autowire</code> &#x5C06;&#x5B83;&#x4EEC;&#x76F4;&#x63A5;&#x6CE8;&#x5165;&#x60A8;&#x7684; bean &#x4E2D;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation</span><span class="token punctuation">.</span><span class="token class-name">Autowired</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>jdbc<span class="token punctuation">.</span>core</span><span class="token punctuation">.</span><span class="token class-name">JdbcTemplate</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype</span><span class="token punctuation">.</span><span class="token class-name">Component</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">JdbcTemplate</span> jdbcTemplate<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">JdbcTemplate</span> jdbcTemplate<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>jdbcTemplate <span class="token operator">=</span> jdbcTemplate<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.jdbc.template.*</code> &#x5C5E;&#x6027;&#x6765;&#x81EA;&#x5B9A;&#x4E49;&#x4E00;&#x4E9B; template &#x7684;&#x5C5E;&#x6027;&#xFF0C;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.jdbc.template.max-rows</span><span class="token attr-value"><span class="token punctuation">=</span>500</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p><code>NamedParameterJdbcTemplate</code> &#x5728;&#x5E95;&#x5C42;&#x91CD;&#x7528;&#x4E86;&#x76F8;&#x540C;&#x7684; <code>JdbcTemplate</code> &#x5B9E;&#x4F8B;&#x3002;&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86;&#x591A;&#x4E2A; <code>JdbcTemplate</code> &#x4E14;&#x6CA1;&#x6709;&#x58F0;&#x660E; primary &#x4E3B;&#x5019;&#x9009;&#xFF0C;&#x5219;&#x4E0D;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E; <code>NamedParameterJdbcTemplate</code>&#x3002;</p>
</blockquote>
<p><a id="boot-features-jpa-and-spring-data"></a></p>
<h3 id="303&#x3001;jpa-&#x4E0E;-spring-data-jpa">30.3&#x3001;JPA &#x4E0E; Spring Data JPA</h3>
<p>Java Persistence API&#xFF08;Java &#x6301;&#x4E45;&#x5316; API&#xFF09;&#x662F;&#x4E00;&#x9879;&#x6807;&#x51C6;&#x6280;&#x672F;&#xFF0C;&#x53EF;&#x8BA9;&#x60A8;&#x5C06;&#x5BF9;&#x8C61;<strong>&#x6620;&#x5C04;</strong>&#x5230;&#x5173;&#x7CFB;&#x6570;&#x636E;&#x5E93;&#x3002;<code>spring-boot-starter-data-jpa</code> POM &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x5FEB;&#x901F;&#x8D77;&#x6B65;&#x7684;&#x65B9;&#x6CD5;&#x3002;&#x5B83;&#x63D0;&#x4F9B;&#x4E86;&#x4EE5;&#x4E0B;&#x5173;&#x952E;&#x4F9D;&#x8D56;&#xFF1A;</p>
<ul>
<li><strong>Hibernate</strong> &#x2009;&#x2014;&#x2014;&#x2009; &#x6700;&#x53D7;&#x6B22;&#x8FCE;&#x7684; JPA &#x5B9E;&#x73B0;&#x4E4B;&#x4E00;&#x3002;</li>
<li><strong>Spring Data JPA</strong> &#x2014;&#x2014; &#x2009;&#x53EF;&#x4EE5;&#x8F7B;&#x677E;&#x5730;&#x5B9E;&#x73B0;&#x57FA;&#x4E8E; JPA &#x7684;&#x8D44;&#x6E90;&#x5E93;&#x3002;</li>
<li><strong>Spring ORM</strong> &#x2009;&#x2014;&#x2014; &#x2009;Spring Framework &#x7684;&#x6838;&#x5FC3; ORM &#x652F;&#x6301;</li>
</ul>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6211;&#x4EEC;&#x4E0D;&#x4F1A;&#x5728;&#x8FD9;&#x91CC;&#x4ECB;&#x7ECD;&#x592A;&#x591A;&#x5173;&#x4E8E; JPA &#x6216;&#x8005; <a href="https://projects.spring.io/spring-data/" target="_blank">Spring Data</a> &#x7684;&#x76F8;&#x5173;&#x5185;&#x5BB9;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <a href="https://spring.io/" target="_blank">spring.io</a> &#x4E0A;&#x67E5;&#x770B;<a href="https://spring.io/guides/gs/accessing-data-jpa/" target="_blank">&#x4F7F;&#x7528; JPA &#x8BBF;&#x95EE;&#x6570;&#x636E;</a>&#xFF0C;&#x83B7;&#x53D6;&#x9605;&#x8BFB; <a href="https://projects.spring.io/spring-data-jpa/" target="_blank">Spring Data JPA</a> &#x548C; <a href="https://hibernate.org/orm/documentation/" target="_blank">Hibernate</a> &#x7684;&#x53C2;&#x8003;&#x6587;&#x6863;&#x3002;</p>
</blockquote>
<p><a id="boot-features-jpa-and-spring-data"></a></p>
<h4 id="3031&#x3001;&#x5B9E;&#x4F53;&#x7C7B;">30.3.1&#x3001;&#x5B9E;&#x4F53;&#x7C7B;</h4>
<p>&#x901A;&#x5E38;&#xFF0C;JPA <strong>Entity</strong>&#xFF08;&#x5B9E;&#x4F53;&#xFF09;&#x7C7B;&#x662F;&#x5728; <code>persistence.xml</code> &#x6587;&#x4EF6;&#x4E2D;&#x6307;&#x5B9A;&#x7684;&#x3002;&#x4F7F;&#x7528;&#x4E86; Spring Boot&#xFF0C;&#x8BE5;&#x6587;&#x4EF6;&#x5C06;&#x4E0D;&#x662F;&#x5FC5;&#x9700;&#x7684;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <strong>Entity Scanning</strong>&#xFF08;&#x5B9E;&#x4F53;&#x626B;&#x63CF;&#xFF09;&#x6765;&#x4EE3;&#x66FF;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5C06;&#x641C;&#x7D22;&#x4E3B;&#x914D;&#x7F6E;&#x7C7B;&#xFF08;&#x4F7F;&#x7528;&#x4E86; <code>@EnableAutoConfiguration</code> &#x6216; <code>@SpringBootApplication</code> &#x6CE8;&#x89E3;&#xFF09;&#x4E0B;&#x9762;&#x7684;&#x6240;&#x6709;&#x5305;&#x3002;</p>
<p>&#x4EFB;&#x4F55;&#x7528;&#x4E86; <code>@Entity</code>&#x3001;<code>@Embeddable</code> &#x6216;&#x8005; <code>@MappedSuperclass</code> &#x6CE8;&#x89E3;&#x7684;&#x7C7B;&#x5C06;&#x88AB;&#x8003;&#x8651;&#x3002;&#x4E00;&#x4E2A;&#x5178;&#x578B;&#x7684;&#x5B9E;&#x4F53;&#x7C7B;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>example<span class="token punctuation">.</span>myapp<span class="token punctuation">.</span>domain</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>io</span><span class="token punctuation">.</span><span class="token class-name">Serializable</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">javax<span class="token punctuation">.</span>persistence</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>

<span class="token annotation punctuation">@Entity</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">City</span> <span class="token keyword">implements</span> <span class="token class-name">Serializable</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Id</span>
    <span class="token annotation punctuation">@GeneratedValue</span>
    <span class="token keyword">private</span> <span class="token class-name">Long</span> id<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Column</span><span class="token punctuation">(</span>nullable <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Column</span><span class="token punctuation">(</span>nullable <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span>
    <span class="token keyword">private</span> <span class="token class-name">String</span> state<span class="token punctuation">;</span>

    <span class="token comment">// ... additional members, often include @OneToMany mappings</span>

    <span class="token keyword">protected</span> <span class="token class-name">City</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// no-args constructor required by JPA spec</span>
        <span class="token comment">// this one is protected since it shouldn&apos;t be used directly</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">City</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">,</span> <span class="token class-name">String</span> state<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>name <span class="token operator">=</span> name<span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>state <span class="token operator">=</span> state<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>name<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">String</span> <span class="token function">getState</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>state<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ... etc</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@EntityScan</code> &#x6CE8;&#x89E3;&#x81EA;&#x5B9A;&#x4E49;&#x5B9E;&#x4F53;&#x7C7B;&#x7684;&#x626B;&#x63CF;&#x4F4D;&#x7F6E;&#x3002;&#x8BF7;&#x53C2;&#x89C1;<a href="https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/reference/htmlsingle/#howto-separate-entity-definitions-from-spring-configuration" target="_blank">84.4&#x3001;&#x4ECE; Spring configuration &#x914D;&#x7F6E;&#x4E2D;&#x5206;&#x79BB; @Entity &#x5B9A;&#x4E49;</a>&#x7AE0;&#x8282;&#x3002;</p>
</blockquote>
<p><a id="boot-features-spring-data-jpa-repositories"></a></p>
<h4 id="3032&#x3001;spring-data-jpa-&#x8D44;&#x6E90;&#x5E93;">30.3.2&#x3001;Spring Data JPA &#x8D44;&#x6E90;&#x5E93;</h4>
<p><a href="https://projects.spring.io/spring-data-jpa/" target="_blank">Spring Data JPA</a> &#x8D44;&#x6E90;&#x5E93;&#xFF08;repository&#xFF09;&#x662F;&#x63A5;&#x53E3;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5B9A;&#x4E49;&#x7528;&#x4E8E;&#x8BBF;&#x95EE;&#x6570;&#x636E;&#x3002;JAP &#x67E5;&#x8BE2;&#x662F;&#x6839;&#x636E;&#x60A8;&#x7684;&#x65B9;&#x6CD5;&#x540D;&#x81EA;&#x52A8;&#x521B;&#x5EFA;&#x3002;&#x4F8B;&#x5982;&#xFF0C;<code>CityRepository</code> &#x63A5;&#x53E3;&#x53EF;&#x4EE5;&#x58F0;&#x660E; <code>findAllByState(String state)</code> &#x65B9;&#x6CD5;&#x6765;&#x67E5;&#x627E;&#x6307;&#x5B9A;&#x72B6;&#x6001;&#x4E0B;&#x7684;&#x6240;&#x6709;&#x57CE;&#x5E02;&#x3002;</p>
<p>&#x5BF9;&#x4E8E;&#x66F4;&#x52A0;&#x590D;&#x6742;&#x7684;&#x67E5;&#x8BE2;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; Spring Data &#x7684; <a href="https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/Query.html" target="_blank"><code>Query</code></a> &#x6CE8;&#x89E3;</p>
<p>Spring Data &#x8D44;&#x6E90;&#x5E93;&#x901A;&#x5E38;&#x7EE7;&#x627F;&#x81EA; <a href="https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/Repository.html" target="_blank">Repository</a> &#x6216;&#x8005; <a href="https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/repository/CrudRepository.html" target="_blank">CrudRepository</a> &#x63A5;&#x53E3;&#x3002;&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528;&#x4E86;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x5219;&#x5C06;&#x4ECE;&#x5305;&#x542B;&#x4E3B;&#x914D;&#x7F6E;&#x7C7B;&#xFF08;&#x4F7F;&#x7528;&#x4E86; <code>@EnableAutoConfiguration</code> &#x6216; <code>@SpringBootApplication</code> &#x6CE8;&#x89E3;&#xFF09;&#x7684;&#x5305;&#x4E2D;&#x641C;&#x7D22;&#x8D44;&#x6E90;&#x5E93;&#xFF1A;</p>
<p>&#x4EE5;&#x4E0B;&#x662F;&#x4E00;&#x4E2A;&#x5178;&#x578B;&#x7684; Spring Data &#x8D44;&#x6E90;&#x5E93;&#x63A5;&#x53E3;&#x5B9A;&#x4E49;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>example<span class="token punctuation">.</span>myapp<span class="token punctuation">.</span>domain</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>data<span class="token punctuation">.</span>domain</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>data<span class="token punctuation">.</span>repository</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>

<span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">CityRepository</span> <span class="token keyword">extends</span> <span class="token class-name">Repository</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">City</span><span class="token punctuation">,</span> <span class="token class-name">Long</span><span class="token punctuation">&gt;</span></span> <span class="token punctuation">{</span>

    <span class="token class-name">Page</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">City</span><span class="token punctuation">&gt;</span></span> <span class="token function">findAll</span><span class="token punctuation">(</span><span class="token class-name">Pageable</span> pageable<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token class-name">City</span> <span class="token function">findByNameAndStateAllIgnoringCase</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">,</span> <span class="token class-name">String</span> state<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token punctuation">}</span>
</code></pre>
<p>Spring Data JPA &#x8D44;&#x6E90;&#x5E93;&#x652F;&#x6301;&#x4E09;&#x79CD;&#x4E0D;&#x540C;&#x7684;&#x5F15;&#x5BFC;&#x6A21;&#x5F0F;&#xFF1A;default&#x3001;deferred &#x548C; lazy&#x3002;&#x8981;&#x542F;&#x7528;&#x5EF6;&#x8FDF;&#x6216;&#x61D2;&#x60F0;&#x5F15;&#x5BFC;&#xFF0C;&#x8BF7;&#x5C06; <code>spring.data.jpa.repositories.bootstrap-mode</code> &#x5206;&#x522B;&#x8BBE;&#x7F6E;&#x4E3A; <code>deferred</code> &#x6216; <code>lazy</code>&#x3002;&#x4F7F;&#x7528;&#x5EF6;&#x8FDF;&#x6216;&#x5EF6;&#x8FDF;&#x5F15;&#x5BFC;&#x65F6;&#xFF0C;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>EntityManagerFactoryBuilder</code> &#x5C06;&#x4F7F;&#x7528;&#x4E0A;&#x4E0B;&#x6587;&#x7684;&#x5F02;&#x6B65;&#x4EFB;&#x52A1;&#x6267;&#x884C;&#x5668;&#xFF08;&#x5982;&#x679C;&#x6709;&#xFF09;&#x4F5C;&#x4E3A;&#x5F15;&#x5BFC;&#x7A0B;&#x5E8F;&#x6267;&#x884C;&#x5668;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6211;&#x4EEC;&#x51E0;&#x4E4E;&#x6CA1;&#x6709;&#x63A5;&#x89E6;&#x5230; Spring Data JPA &#x7684;&#x8868;&#x9762;&#x5185;&#x5BB9;&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x67E5;&#x9605; <a href="https://docs.spring.io/spring-data/jpa/docs/current/reference/html/" target="_blank">Spring Data JPA &#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-creating-and-dropping-jpa-databases"></a></p>
<h4 id="3033&#x3001;&#x521B;&#x5EFA;&#x548C;&#x5220;&#x9664;-jpa-&#x6570;&#x636E;&#x5E93;">30.3.3&#x3001;&#x521B;&#x5EFA;&#x548C;&#x5220;&#x9664; JPA &#x6570;&#x636E;&#x5E93;</h4>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;<strong>&#x4EC5;</strong>&#x5F53;&#x60A8;&#x4F7F;&#x7528;&#x4E86;&#x5185;&#x5D4C;&#x6570;&#x636E;&#x5E93;&#xFF08;H2&#x3001;HSQL &#x6216; Derby&#xFF09;&#x65F6;&#x624D;&#x4F1A;&#x81EA;&#x52A8;&#x521B;&#x5EFA; JPA &#x6570;&#x636E;&#x5E93;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.jpa.*</code> &#x5C5E;&#x6027;&#x663E;&#x5F0F;&#x914D;&#x7F6E; JPA &#x8BBE;&#x7F6E;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x8981;&#x521B;&#x5EFA;&#x548C;&#x5220;&#x9664;&#x8868;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5C06;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;&#x6DFB;&#x52A0;&#x5230; <code>application.properties</code> &#x4E2D;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.jpa.hibernate.ddl-auto</span><span class="token attr-value"><span class="token punctuation">=</span>create-drop</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5173;&#x4E8E;&#x4E0A;&#x8FF0;&#x529F;&#x80FD;&#xFF0C;Hibernate &#x81EA;&#x5DF1;&#x7684;&#x5185;&#x90E8;&#x5C5E;&#x6027;&#x540D;&#x79F0;&#xFF08;&#x5982;&#x679C;&#x60A8;&#x8BB0;&#x4F4F;&#x66F4;&#x597D;&#xFF09;&#x4E3A; <code>hibernate.hbm2ddl.auto</code>&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.jpa.properties.*</code>&#xFF08;&#x5728;&#x6DFB;&#x52A0;&#x5230;&#x5B9E;&#x4F53;&#x7BA1;&#x7406;&#x5668;&#x4E4B;&#x524D;&#xFF0C;&#x8BE5;&#x524D;&#x7F00;&#x5C06;&#x88AB;&#x5220;&#x9664;&#xFF09;&#x6765;&#x5C06; Hibernate &#x539F;&#x751F;&#x5C5E;&#x6027;&#x4E00;&#x540C;&#x8BBE;&#x7F6E;&#xFF1A;</p>
</blockquote>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.jpa.properties.hibernate.globally_quoted_identifiers</span><span class="token attr-value"><span class="token punctuation">=</span>true</span>
</code></pre>
<p>&#x4E0A;&#x9762;&#x793A;&#x4F8B;&#x4E2D;&#x5C06; <code>true</code> &#x503C;&#x8BBE;&#x7F6E;&#x7ED9; <code>hibernate.globally_quoted_identifiers</code> &#x5C5E;&#x6027;&#xFF0C;&#x8BE5;&#x5C5E;&#x6027;&#x5C06;&#x4F20;&#x7ED9; Hibernate &#x5B9E;&#x4F53;&#x7BA1;&#x7406;&#x5668;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;DDL &#x6267;&#x884C;&#xFF08;&#x6216;&#x9A8C;&#x8BC1;&#xFF09;&#x5C06;&#x5EF6;&#x8FDF;&#x5230; <code>ApplicationContext</code> &#x542F;&#x52A8;&#x540E;&#x3002;&#x8FD8;&#x6709;&#x4E00;&#x4E2A; <code>spring.jpa.generate-ddl</code> &#x6807;&#x5FD7;&#xFF0C;&#x5982;&#x679C; Hibernate &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x662F;&#x6FC0;&#x6D3B;&#x7684;&#xFF0C;&#x90A3;&#x4E48;&#x5B83;&#x5C06;&#x4E0D;&#x4F1A;&#x88AB;&#x4F7F;&#x7528;&#xFF0C;&#x56E0;&#x4E3A; <code>ddl-auto</code> &#x8BBE;&#x7F6E;&#x66F4;&#x7EC6;&#x7C92;&#x5EA6;&#x3002;</p>
<p><a id="boot-features-jpa-in-web-environment"></a></p>
<h4 id="3034&#x3001;&#x5728;&#x89C6;&#x56FE;&#x4E2D;&#x6253;&#x5F00;-entitymanager">30.3.4&#x3001;&#x5728;&#x89C6;&#x56FE;&#x4E2D;&#x6253;&#x5F00; EntityManager</h4>
<p>&#x5982;&#x679C;&#x60A8;&#x6B63;&#x5728;&#x8FD0;&#x884C; web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;Spring Boot &#x5C06;&#x9ED8;&#x8BA4;&#x6CE8;&#x518C; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/orm/jpa/support/OpenEntityManagerInViewInterceptor.html" target="_blank"><code>OpenEntityManagerInViewInterceptor</code></a> &#x7528;&#x4E8E;<strong>&#x5728;&#x89C6;&#x56FE;&#x4E2D;&#x6253;&#x5F00; EntityManager</strong> &#x6A21;&#x5F0F;&#xFF0C;&#x5373;&#x8FD0;&#x5141;&#x8BB8;&#x5728; web &#x89C6;&#x56FE;&#x4E2D;&#x5EF6;&#x8FDF;&#x52A0;&#x8F7D;&#x3002;&#x5982;&#x679C;&#x60A8;&#x4E0D;&#x60F3;&#x5F00;&#x542F;&#x8FD9;&#x4E2A;&#x884C;&#x4E3A;&#xFF0C;&#x5219;&#x5E94;&#x5728; <code>application.properties</code> &#x4E2D;&#x5C06; <code>spring.jpa.open-in-view</code> &#x8BBE;&#x7F6E;&#x4E3A; <code>false</code>&#x3002;</p>
<p><a id="boot-features-data-jdbc"></a></p>
<h3 id="304&#x3001;spring-data-jdbc">30.4&#x3001;Spring Data JDBC</h3>
<p>Spring Data &#x5305;&#x542B;&#x4E86;&#x5BF9; JDBC &#x8D44;&#x6E90;&#x5E93;&#x7684;&#x652F;&#x6301;&#xFF0C;&#x5E76;&#x5C06;&#x81EA;&#x52A8;&#x4E3A; <code>CrudRepository</code> &#x4E0A;&#x7684;&#x65B9;&#x6CD5;&#x751F;&#x6210; SQL&#x3002;&#x5BF9;&#x4E8E;&#x66F4;&#x9AD8;&#x7EA7;&#x7684;&#x67E5;&#x8BE2;&#xFF0C;&#x5B83;&#x63D0;&#x4F9B;&#x4E86; <code>@Query</code> &#x6CE8;&#x89E3;&#x3002;</p>
<p>&#x5F53; classpath &#x4E0B;&#x5B58;&#x5728;&#x5FC5;&#x8981;&#x7684;&#x4F9D;&#x8D56;&#x65F6;&#xFF0C;Spring Boot &#x5C06;&#x81EA;&#x52A8;&#x914D;&#x7F6E; Spring Data &#x7684; JDBC &#x8D44;&#x6E90;&#x5E93;&#x3002;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6DFB;&#x52A0;&#x5355;&#x4E2A; <code>spring-boot-starter-data-jdbc</code> &#x4F9D;&#x8D56;&#x5F15;&#x5165;&#x5230;&#x9879;&#x76EE;&#x4E2D;&#x3002;&#x5982;&#x6709;&#x5FC5;&#x8981;&#xFF0C;&#x53EF;&#x901A;&#x8FC7;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x6DFB;&#x52A0; <code>@EnableJdbcRepositories</code> &#x6CE8;&#x89E3;&#x6216; <code>JdbcConfiguration</code> &#x5B50;&#x7C7B;&#x6765;&#x63A7;&#x5236; Spring Data JDBC &#x7684;&#x914D;&#x7F6E;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6709;&#x5173; Spring Data JDBC &#x7684;&#x5B8C;&#x6574;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605;<a href="https://projects.spring.io/spring-data-jdbc/" target="_blank">&#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-sql-h2-console"></a></p>
<h3 id="305&#x3001;&#x4F7F;&#x7528;-h2-&#x7684;-web-&#x63A7;&#x5236;&#x53F0;">30.5&#x3001;&#x4F7F;&#x7528; H2 &#x7684; Web &#x63A7;&#x5236;&#x53F0;</h3>
<p><a href="http://www.h2database.com/" target="_blank">H2 &#x6570;&#x636E;&#x5E93;</a>&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;<a href="http://www.h2database.com/html/quickstart.html#h2_console" target="_blank">&#x57FA;&#x4E8E;&#x6D4F;&#x89C8;&#x5668;&#x7684;&#x63A7;&#x5236;&#x53F0;</a>&#xFF0C;Spring Boot &#x53EF;&#x4EE5;&#x4E3A;&#x60A8;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x5F53;&#x6EE1;&#x8DB3;&#x4EE5;&#x4E0B;&#x6761;&#x4EF6;&#x65F6;&#xFF0C;&#x63A7;&#x5236;&#x53F0;&#x5C06;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF1A;</p>
<ul>
<li>&#x60A8;&#x5F00;&#x53D1;&#x7684;&#x662F;&#x4E00;&#x4E2A;&#x57FA;&#x4E8E; servlet &#x7684; web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;</li>
<li><code>com.h2database:h2</code> &#x5728; classpath &#x4E0A;</li>
<li>&#x60A8;&#x4F7F;&#x7528;&#x4E86; <a href="#using-boot-devtools">Spring Boot &#x7684;&#x5F00;&#x53D1;&#x8005;&#x5DE5;&#x5177;</a></li>
</ul>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x4E0D;&#x4F7F;&#x7528; Spring Boot &#x7684;&#x5F00;&#x53D1;&#x8005;&#x5DE5;&#x5177;&#xFF0C;&#x4F46;&#x4ECD;&#x5E0C;&#x671B;&#x4F7F;&#x7528; H2 &#x7684;&#x63A7;&#x5236;&#x53F0;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5C06; <code>spring.h2.console.enabled</code> &#x5C5E;&#x6027;&#x8BBE;&#x7F6E;&#x4E3A; <code>true</code> &#x6765;&#x5B9E;&#x73B0;&#x3002;</p>
</blockquote>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>H2 &#x63A7;&#x5236;&#x53F0;&#x4EC5;&#x7528;&#x4E8E;&#x5F00;&#x53D1;&#x671F;&#x95F4;&#xFF0C;&#x56E0;&#x6B64;&#x5E94;&#x6CE8;&#x610F;&#x786E;&#x4FDD; <code>spring.h2.console.enabled</code> &#x5728;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x4E2D;<strong>&#x6CA1;&#x6709;</strong>&#x8BBE;&#x7F6E;&#x4E3A; <code>true</code>&#x3002;</p>
</blockquote>
<p><a id="boot-features-sql-h2-console-custom-path"></a></p>
<h4 id="3051&#x3001;&#x66F4;&#x6539;-h2-&#x63A7;&#x5236;&#x53F0;&#x7684;&#x8DEF;&#x5F84;">30.5.1&#x3001;&#x66F4;&#x6539; H2 &#x63A7;&#x5236;&#x53F0;&#x7684;&#x8DEF;&#x5F84;</h4>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x63A7;&#x5236;&#x53F0;&#x7684;&#x8DEF;&#x5F84;&#x4E3A; <code>/h2-console</code>&#x3002;&#x4F60;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.h2.console.path</code> &#x5C5E;&#x6027;&#x6765;&#x81EA;&#x5B9A;&#x4E49;&#x63A7;&#x5236;&#x53F0;&#x7684;&#x8DEF;&#x5F84;&#x3002;</p>
<p><a id="boot-features-jooq"></a></p>
<h3 id="306&#x3001;&#x4F7F;&#x7528;-jooq">30.6&#x3001;&#x4F7F;&#x7528; jOOQ</h3>
<p>Java &#x9762;&#x5411;&#x5BF9;&#x8C61;&#x67E5;&#x8BE2;&#xFF08;<a href="http://www.jooq.org/" target="_blank">Java Object Oriented Querying&#xFF0C;jOOQ</a>&#xFF09;&#x662F;&#x4E00;&#x6B3E;&#x5E7F;&#x53D7;&#x6B22;&#x8FCE;&#x7684;&#x4EA7;&#x54C1;&#xFF0C;&#x51FA;&#x81EA; <a href="http://www.datageekery.com/" target="_blank">Data Geekery</a>&#xFF0C;&#x5B83;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6570;&#x636E;&#x5E93;&#x751F;&#x6210; Java &#x4EE3;&#x7801;&#xFF0C;&#x5E76;&#x5141;&#x8BB8;&#x60A8;&#x4F7F;&#x7528;&#x6D41;&#x5F0F; API &#x6765;&#x6784;&#x5EFA;&#x7C7B;&#x578B;&#x5B89;&#x5168;&#x7684; SQL &#x67E5;&#x8BE2;&#x3002;&#x5546;&#x4E1A;&#x7248;&#x548C;&#x5F00;&#x6E90;&#x7248;&#x90FD;&#x53EF;&#x4EE5;&#x4E0E; Spring Boot &#x4E00;&#x8D77;&#x4F7F;&#x7528;&#x3002;</p>
<p><a id="_code_generation"></a></p>
<h4 id="3061&#x3001;&#x4EE3;&#x7801;&#x751F;&#x6210;">30.6.1&#x3001;&#x4EE3;&#x7801;&#x751F;&#x6210;</h4>
<p>&#x8981;&#x4F7F;&#x7528; jOOQ &#x7684;&#x7C7B;&#x578B;&#x5B89;&#x5168;&#x67E5;&#x8BE2;&#xFF0C;&#x60A8;&#x9700;&#x8981;&#x4ECE;&#x6570;&#x636E;&#x5E93;&#x6A21;&#x5F0F;&#x751F;&#x6210; Java &#x7C7B;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x6309;&#x7167; <a href="https://www.jooq.org/doc/3.11.7/manual-single-page/#jooq-in-7-steps-step3" target="_blank">jOOQ &#x7528;&#x6237;&#x624B;&#x518C;</a>&#x4E2D;&#x7684;&#x8BF4;&#x660E;&#x8FDB;&#x884C;&#x64CD;&#x4F5C;&#x3002;&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528;&#x4E86; <code>jooq-codegen-maven</code> &#x63D2;&#x4EF6;&#xFF0C;&#x5E76;&#x4E14;&#x8FD8;&#x4F7F;&#x7528;&#x4E86; <code>spring-boot-starter-parent</code> &#x7236; POM&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5B89;&#x5168;&#x5730;&#x7701;&#x7565;&#x6389;&#x63D2;&#x4EF6;&#x7684; <code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span></code> &#x6807;&#x7B7E;&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; Spring Boot &#x5B9A;&#x4E49;&#x7684;&#x7248;&#x672C;&#x53D8;&#x91CF;&#xFF08;&#x4F8B;&#x5982; <code>h2.version</code>&#xFF09;&#x6765;&#x58F0;&#x660E;&#x63D2;&#x4EF6;&#x7684;&#x6570;&#x636E;&#x5E93;&#x4F9D;&#x8D56;&#x3002;&#x4EE5;&#x4E0B;&#x662F;&#x4E00;&#x4E2A;&#x793A;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>plugin</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.jooq<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>jooq-codegen-maven<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>executions</span><span class="token punctuation">&gt;</span></span>
        ...
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>executions</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependencies</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>com.h2database<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>h2<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>version</span><span class="token punctuation">&gt;</span></span>${h2.version}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>version</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependencies</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>configuration</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>jdbc</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>driver</span><span class="token punctuation">&gt;</span></span>org.h2.Driver<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>driver</span><span class="token punctuation">&gt;</span></span>
            <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>url</span><span class="token punctuation">&gt;</span></span>jdbc:h2:~/yourdatabase<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>url</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>jdbc</span><span class="token punctuation">&gt;</span></span>
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>generator</span><span class="token punctuation">&gt;</span></span>
            ...
        <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>generator</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>configuration</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>plugin</span><span class="token punctuation">&gt;</span></span>
</code></pre>
<p><a id="_using_dslcontext"></a></p>
<h4 id="3062&#x3001;&#x4F7F;&#x7528;-dslcontext">30.6.2&#x3001;&#x4F7F;&#x7528; DSLContext</h4>
<p>jOOQ &#x63D0;&#x4F9B;&#x7684;&#x6D41;&#x5F0F; API &#x662F;&#x901A;&#x8FC7; <code>org.jooq.DSLContext</code> &#x63A5;&#x53E3;&#x521D;&#x59CB;&#x5316;&#x7684;&#x3002;Spring Boot &#x5C06;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A; <code>DSLContext</code> &#x4F5C;&#x4E3A; Spring Bean&#xFF0C;&#x5E76;&#x4E14;&#x5C06;&#x5176;&#x8FDE;&#x63A5;&#x5230;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684; <code>DataSource</code>&#x3002;<code>&#x8981;&#x4F7F;&#x7528; DSLContext</code>&#xFF0C;&#x60A8;&#x53EA;&#x9700;&#x8981; <code>@Autowire</code> &#x5B83;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">JooqExample</span> <span class="token keyword">implements</span> <span class="token class-name">CommandLineRunner</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">DSLContext</span> create<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">JooqExample</span><span class="token punctuation">(</span><span class="token class-name">DSLContext</span> dslContext<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>create <span class="token operator">=</span> dslContext<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>jOOQ &#x624B;&#x518C;&#x5EFA;&#x8BAE;&#x4F7F;&#x7528;&#x540D;&#x4E3A; <code>create</code> &#x7684;&#x53D8;&#x91CF;&#x6765;&#x4FDD;&#x5B58; <code>DSLContext</code>&#x3002;</p>
</blockquote>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>DSLContext</code> &#x6784;&#x5EFA;&#x67E5;&#x8BE2;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">public</span> <span class="token class-name">List</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">GregorianCalendar</span><span class="token punctuation">&gt;</span></span> <span class="token function">authorsBornAfter1980</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>create<span class="token punctuation">.</span><span class="token function">selectFrom</span><span class="token punctuation">(</span>AUTHOR<span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">where</span><span class="token punctuation">(</span>AUTHOR<span class="token punctuation">.</span>DATE_OF_BIRTH<span class="token punctuation">.</span><span class="token function">greaterThan</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">GregorianCalendar</span><span class="token punctuation">(</span><span class="token number">1980</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">fetch</span><span class="token punctuation">(</span>AUTHOR<span class="token punctuation">.</span>DATE_OF_BIRTH<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p><a id="_jooq_sql_dialect"></a></p>
<h4 id="3063&#x3001;jooq-sql-&#x65B9;&#x8A00;">30.6.3&#x3001;jOOQ SQL &#x65B9;&#x8A00;</h4>
<p>&#x9664;&#x975E;&#x914D;&#x7F6E;&#x4E86; <code>spring.jooq.sql-dialect</code> &#x5C5E;&#x6027;&#xFF0C;&#x5426;&#x5219; Spring Boot &#x4F1A;&#x81EA;&#x52A8;&#x5224;&#x5B9A;&#x7528;&#x4E8E;&#x6570;&#x636E;&#x6E90;&#x7684; SQL &#x65B9;&#x8A00;&#x3002;&#x5982;&#x679C; Spring Boot &#x65E0;&#x6CD5;&#x68C0;&#x6D4B;&#x5230;&#x65B9;&#x8A00;&#xFF0C;&#x5219;&#x4F7F;&#x7528; <code>DEFAULT</code>&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>Spring Boot &#x53EA;&#x80FD;&#x81EA;&#x52A8;&#x914D;&#x7F6E; jOOQ &#x5F00;&#x6E90;&#x7248;&#x672C;&#x652F;&#x6301;&#x7684;&#x65B9;&#x8A00;&#x3002;</p>
</blockquote>
<p><a id="_customizing_jooq"></a></p>
<h4 id="3064&#x3001;&#x81EA;&#x5B9A;&#x4E49;-jooq">30.6.4&#x3001;&#x81EA;&#x5B9A;&#x4E49; jOOQ</h4>
<p>&#x53EF;&#x901A;&#x8FC7;&#x5B9A;&#x4E49;&#x81EA;&#x5DF1;&#x7684; <code>@Bean</code> &#x6765;&#x5B9E;&#x73B0;&#x66F4;&#x9AD8;&#x7EA7;&#x7684;&#x529F;&#x80FD;&#xFF0C;&#x8FD9;&#x4E9B;&#x81EA;&#x5B9A;&#x4E49;&#x5C06;&#x5728;&#x521B;&#x5EFA; jOOQ <code>Configuration</code> &#x65F6;&#x4F7F;&#x7528;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4E3A;&#x4EE5;&#x4E0B; jOOQ &#x7C7B;&#x578B;&#x5B9A;&#x4E49; bean&#xFF1A;</p>
<ul>
<li><code>ConnectionProvider</code></li>
<li><code>ExecutorProvider</code></li>
<li><code>TransactionProvider</code></li>
<li><code>RecordMapperProvider</code></li>
<li><code>RecordUnmapperProvider</code></li>
<li><code>RecordListenerProvider</code></li>
<li><code>ExecuteListenerProvider</code></li>
<li><code>VisitListenerProvider</code></li>
<li><code>TransactionListenerProvider</code></li>
</ul>
<p>&#x5982;&#x679C;&#x8981;&#x5B8C;&#x5168;&#x63A7;&#x5236; jOOQ &#x914D;&#x7F6E;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x521B;&#x5EFA;&#x81EA;&#x5DF1;&#x7684; <code>org.jooq.Configuration</code> <code>@Bean</code>&#x3002;</p>
<p><a id="boot-features-nosql"></a></p>
<h2 id="31&#x3001;&#x4F7F;&#x7528;-nosql-&#x6280;&#x672F;">31&#x3001;&#x4F7F;&#x7528; NoSQL &#x6280;&#x672F;</h2>
<p>Spring Data &#x63D0;&#x4F9B;&#x4E86;&#x5176;&#x4ED6;&#x9879;&#x76EE;&#xFF0C;&#x53EF;&#x4EE5;&#x5E2E;&#x52A9;&#x60A8;&#x8BBF;&#x95EE;&#x5404;&#x79CD; NoSQL &#x6280;&#x672F;&#xFF0C;&#x5305;&#x62EC; <a href="https://projects.spring.io/spring-data-mongodb/" target="_blank">MongoDB</a>&#x3001;<a href="https://projects.spring.io/spring-data-neo4j/" target="_blank">Neo4J</a>&#x3001;<a href="https://github.com/spring-projects/spring-data-elasticsearch/" target="_blank">Elasticsearch</a>&#x3001;<a href="https://projects.spring.io/spring-data-solr/" target="_blank">Solr</a>&#x3001;<a href="https://projects.spring.io/spring-data-redis/" target="_blank">Redis</a>&#x3001;<a href="https://projects.spring.io/spring-data-gemfire/" target="_blank">Gemfire</a>&#x3001;<a href="https://projects.spring.io/spring-data-cassandra/" target="_blank">Cassandra</a>&#x3001;<a href="https://projects.spring.io/spring-data-couchbase/" target="_blank">Couchbase</a> &#x548C; <a href="https://projects.spring.io/spring-data-ldap/" target="_blank">LDAP</a>&#x3002;Spring Boot &#x4E3A; Redis&#x3001;MongoDB&#x3001;Neo4j&#x3001;Elasticsearch&#x3001;Solr&#x3001;Cassandra&#x3001;Couchbase &#x548C; LDAP &#x63D0;&#x4F9B;&#x4E86;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x60A8;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x5176;&#x4ED6;&#x9879;&#x76EE;&#xFF0C;&#x4F46;&#x60A8;&#x9700;&#x8981;&#x81EA;&#x884C;&#x914D;&#x7F6E;&#x4ED6;&#x4EEC;&#x3002;&#x8BF7;&#x53C2;&#x9605; <a href="https://projects.spring.io/spring-data" target="_blank">projects.spring.io/spring-data</a> &#x4E2D;&#x76F8;&#x5E94;&#x7684;&#x53C2;&#x8003;&#x6587;&#x6863;&#x3002;</p>
<p><a id="boot-features-redis"></a></p>
<h3 id="311&#x3001;redis">31.1&#x3001;Redis</h3>
<p><a href="http://redis.io/" target="_blank">Redis</a> &#x662F;&#x4E00;&#x4E2A;&#x96C6;&#x7F13;&#x5B58;&#x3001;&#x6D88;&#x606F;&#x4EE3;&#x7406;&#x548C;&#x952E;&#x503C;&#x5B58;&#x50A8;&#x7B49;&#x4E30;&#x5BCC;&#x529F;&#x80FD;&#x7684;&#x6570;&#x636E;&#x5E93;&#x3002;Spring Boot &#x4E3A; <a href="https://github.com/lettuce-io/lettuce-core/" target="_blank">Lettuce</a> &#x548C; <a href="https://github.com/xetorthio/jedis/" target="_blank">Jedis &#x5BA2;&#x6237;&#x7AEF;&#x7C7B;&#x5E93;</a>&#x63D0;&#x4F9B;&#x4E86;&#x57FA;&#x672C;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;<a href="https://github.com/spring-projects/spring-data-redis" target="_blank">Spring Data Redis</a> &#x4E3A;&#x4ED6;&#x4EEC;&#x63D0;&#x4F9B;&#x4E86;&#x4E0A;&#x5C42;&#x62BD;&#x8C61;&#x3002;</p>
<p>&#x4F7F;&#x7528; <code>spring-boot-starter-data-redis</code> starter &#x53EF;&#x65B9;&#x4FBF;&#x5730;&#x5F15;&#x5165;&#x76F8;&#x5173;&#x4F9D;&#x8D56;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5B83;&#x4F7F;&#x7528; <a href="https://github.com/lettuce-io/lettuce-core/" target="_blank">Lettuce</a>&#x3002;&#x8BE5; starter &#x53EF;&#x5904;&#x7406;&#x4F20;&#x7EDF;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x548C;&#x54CD;&#x5E94;&#x5F0F;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6211;&#x4EEC;&#x8FD8;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A; <code>spring-boot-starter-data-redis-reactive</code> starter&#xFF0C;&#x4EE5;&#x4FBF;&#x4E0E;&#x5176;&#x4ED6;&#x5E26;&#x6709;&#x54CD;&#x5E94;&#x5F0F;&#x652F;&#x6301;&#x7684;&#x5B58;&#x50A8;&#x4FDD;&#x6301;&#x4E00;&#x81F4;&#x3002;</p>
</blockquote>
<p><a id="boot-features-connecting-to-redis"></a></p>
<h4 id="3111&#x3001;&#x8FDE;&#x63A5;-redis">31.1.1&#x3001;&#x8FDE;&#x63A5; Redis</h4>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x50CF;&#x6240;&#x6709; Spring Bean &#x4E00;&#x6837;&#x6CE8;&#x5165;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>RedisConnectionFactory</code>&#x3001;<code>StringRedisTemplate</code> &#x6216;&#x666E;&#x901A;&#x7684; <code>RedisTemplate</code> &#x5B9E;&#x4F8B;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5B9E;&#x4F8B;&#x5C06;&#x5C1D;&#x8BD5;&#x5728; <code>localhost:6379</code> &#x4E0A;&#x8FDE;&#x63A5; Redis &#x670D;&#x52A1;&#x5668;&#xFF0C;&#x4EE5;&#x4E0B;&#x662F; bean &#x793A;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token class-name">StringRedisTemplate</span> template<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">StringRedisTemplate</span> template<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>template <span class="token operator">=</span> template<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x6CE8;&#x518C;&#x4EFB;&#x610F;&#x6570;&#x91CF;&#x4E2A;&#x5B9E;&#x73B0;&#x4E86; <code>LettuceClientConfigurationBuilderCustomizer</code> &#x7684; bean&#xFF0C;&#x4EE5;&#x8FDB;&#x884C;&#x66F4;&#x9AD8;&#x7EA7;&#x7684;&#x81EA;&#x5B9A;&#x4E49;&#x3002;&#x5982;&#x679C;&#x4F60;&#x4F7F;&#x7528; Jedis&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>JedisClientConfigurationBuilderCustomizer</code>&#x3002;</p>
</blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x6DFB;&#x52A0;&#x4E86;&#x81EA;&#x5DF1;&#x7684;&#x4EFB;&#x4F55;&#x4E00;&#x4E2A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7C7B;&#x578B;&#x7684; <code>@Bean</code>&#xFF0C;&#x5B83;&#x5C06;&#x66FF;&#x6362;&#x9ED8;&#x8BA4;&#x8BBE;&#x7F6E;&#xFF08;&#x9664;&#x4E86; <code>RedisTemplate</code>&#xFF0C;&#x7531;&#x4E8E;&#x6392;&#x9664;&#x662F;&#x57FA;&#x4E8E; bean &#x540D;&#x79F0;&#xFF0C;&#x800C; <code>redisTemplate</code> &#x4E0D;&#x662F;&#x5B83;&#x7684;&#x7C7B;&#x578B;&#xFF09;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5982;&#x679C; <code>commons-pool2</code> &#x5728; classpath &#x4E0A;&#xFF0C;&#x60A8;&#x5C06;&#x83B7;&#x5F97;&#x4E00;&#x4E2A;&#x8FDE;&#x63A5;&#x6C60;&#x5DE5;&#x5382;&#x3002;</p>
<p><a id="boot-features-mongodb"></a></p>
<h3 id="312&#x3001;mongodb">31.2&#x3001;MongoDB</h3>
<p><a href="https://www.mongodb.com/" target="_blank">MongoDB</a> &#x662F;&#x4E00;&#x4E2A;&#x5F00;&#x6E90;&#x7684; NoSQL &#x6587;&#x6863;&#x6570;&#x636E;&#x5E93;&#xFF0C;&#x5176;&#x4F7F;&#x7528;&#x4E86;&#x7C7B;&#x4F3C; JSON &#x7684;&#x6A21;&#x5F0F;&#xFF08;schema&#xFF09;&#x6765;&#x66FF;&#x4EE3;&#x4F20;&#x7EDF;&#x57FA;&#x4E8E;&#x8868;&#x7684;&#x5173;&#x7CFB;&#x6570;&#x636E;&#x3002;Spring Boot &#x4E3A; MongoDB &#x63D0;&#x4F9B;&#x4E86;&#x51E0;&#x79CD;&#x4FBF;&#x5229;&#x7684;&#x4F7F;&#x7528;&#x65B9;&#x5F0F;&#xFF0C;&#x5305;&#x62EC; <code>spring-boot-starter-data-mongodb</code> &#x548C; <code>spring-boot-starter-data-mongodb-reactive</code> starter&#x3002;</p>
<p><a id="boot-features-connecting-to-mongodb"></a></p>
<h4 id="3121&#x3001;&#x8FDE;&#x63A5;-mongodb-&#x6570;&#x636E;&#x5E93;">31.2.1&#x3001;&#x8FDE;&#x63A5; MongoDB &#x6570;&#x636E;&#x5E93;</h4>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x6CE8;&#x5165;&#x4E00;&#x4E2A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>org.springframework.data.mongodb.MongoDbFactory</code> &#x6765;&#x8BBF;&#x95EE; Mongo &#x6570;&#x636E;&#x5E93;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x8BE5;&#x5B9E;&#x4F8B;&#x5C06;&#x5C1D;&#x8BD5;&#x5728; <code>mongodb://localhost/test</code> &#x4E0A;&#x8FDE;&#x63A5; MongoDB &#x670D;&#x52A1;&#x5668;&#xFF0C;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x8FDE;&#x63A5;&#x5230; MongoDB &#x6570;&#x636E;&#x5E93;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>data<span class="token punctuation">.</span>mongodb</span><span class="token punctuation">.</span><span class="token class-name">MongoDbFactory</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">com<span class="token punctuation">.</span>mongodb</span><span class="token punctuation">.</span>DB<span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">MongoDbFactory</span> mongo<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">MongoDbFactory</span> mongo<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>mongo <span class="token operator">=</span> mongo<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">example</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">DB</span> db <span class="token operator">=</span> mongo<span class="token punctuation">.</span><span class="token function">getDb</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>spring.data.mongodb.uri</code> &#x5C5E;&#x6027;&#x6765;&#x66F4;&#x6539; URL &#x548C;&#x914D;&#x7F6E;&#x5176;&#x4ED6;&#x8BBE;&#x7F6E;&#xFF0C;&#x5982;<strong>&#x526F;&#x672C;&#x96C6;</strong>&#xFF08;replica set&#xFF09;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.data.mongodb.uri</span><span class="token attr-value"><span class="token punctuation">=</span>mongodb://user:secret@mongo1.example.com:12345,mongo2.example.com:23456/test</span>
</code></pre>
<p>&#x53E6;&#x5916;&#xFF0C;&#x53EA;&#x8981;&#x60A8;&#x4F7F;&#x7528;&#x4E86; Mongo 2.x&#xFF0C;&#x8BF7;&#x6307;&#x5B9A; <code>host</code>/<code>port</code>&#x3002;&#x6BD4;&#x5982;&#xFF0C;&#x60A8;&#x53EF;&#x80FD;&#x8981;&#x5728; <code>application.properties</code> &#x4E2D;&#x58F0;&#x660E;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.data.mongodb.host</span><span class="token attr-value"><span class="token punctuation">=</span>mongoserver</span>
<span class="token constant">spring.data.mongodb.port</span><span class="token attr-value"><span class="token punctuation">=</span>27017</span>
</code></pre>
<p>&#x5982;&#x679C;&#x60A8;&#x5DF2;&#x7ECF;&#x5B9A;&#x4E49;&#x4E86;&#x81EA;&#x5DF1;&#x7684; <code>MongoClient</code>&#xFF0C;&#x5B83;&#x5C06;&#x88AB;&#x7528;&#x4E8E;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x5408;&#x9002;&#x7684; <code>MongoDbFactory</code>&#x3002;&#x652F;&#x6301; <code>com.mongodb.MongoClient</code> &#x548C; <code>com.mongodb.client.MongoClient</code>&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528; Mongo 3.0 Java &#x9A71;&#x52A8;&#xFF0C;&#x5219;&#x4E0D;&#x652F;&#x6301; <code>spring.data.mongodb.host</code> &#x548C; <code>spring.data.mongodb.port</code>&#x3002;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5E94;&#x8BE5;&#x4F7F;&#x7528; <code>spring.data.mongodb.uri</code> &#x6765;&#x63D0;&#x4F9B;&#x6240;&#x6709;&#x914D;&#x7F6E;&#x3002;</p>
</blockquote>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x672A;&#x6307;&#x5B9A; <code>spring.data.mongodb.port</code>&#xFF0C;&#x5219;&#x4F7F;&#x7528;&#x9ED8;&#x8BA4;&#x503C; <code>27017</code>&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x5C06;&#x4E0A;&#x8FF0;&#x793A;&#x4F8B;&#x4E2D;&#x7684;&#x6539;&#x884C;&#x914D;&#x7F6E;&#x5220;&#x9664;&#x6389;&#x3002;</p>
</blockquote>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x4E0D;&#x4F7F;&#x7528; Spring Data Mongo&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x6CE8;&#x5165; <code>com.mongodb.MongoClient</code> bean &#x6765;&#x4EE3;&#x66FF; <code>MongoDbFactory</code>&#x3002;&#x5982;&#x679C;&#x8981;&#x5B8C;&#x5168;&#x63A7;&#x5236;&#x5EFA;&#x7ACB; MongoDB &#x8FDE;&#x63A5;&#xFF0C;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x58F0;&#x660E;&#x81EA;&#x5DF1;&#x7684; <code>MongoDbFactory</code> &#x6216;&#x8005; <code>MongoClient</code> bean&#x3002;</p>
</blockquote>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528;&#x7684;&#x662F;&#x54CD;&#x5E94;&#x5F0F;&#x9A71;&#x52A8;&#xFF0C;&#x5219; SSL &#x9700;&#x8981; Netty&#x3002; &#x5982;&#x679C; Netty &#x53EF;&#x7528;&#x4E14; factory &#x5C1A;&#x672A;&#x81EA;&#x5B9A;&#x4E49;&#xFF0C;&#x5219;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x6B64; factory&#x3002;</p>
</blockquote>
<p><a id="boot-features-mongo-template"></a></p>
<h4 id="3122&#x3001;mongotemplate">31.2.2&#x3001;MongoTemplate</h4>
<p><a href="https://projects.spring.io/spring-data-mongodb/" target="_blank">Spring Data Mongo</a> &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A; <a href="https://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/MongoTemplate.html" target="_blank"><code>MongoTemplate</code></a> &#x7C7B;&#xFF0C;&#x5B83;&#x7684;&#x8BBE;&#x8BA1;&#x4E0E; Spring &#x7684; <code>JdbcTemplate</code> &#x975E;&#x5E38;&#x76F8;&#x4F3C;&#x3002;&#x4E0E; <code>JdbcTemplate</code> &#x4E00;&#x6837;&#xFF0C;Spring Boot &#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A; bean&#xFF0C;&#x4EE5;&#x4FBF;&#x60A8;&#x80FD;&#x6CE8;&#x5165;&#x6A21;&#x677F;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation</span><span class="token punctuation">.</span><span class="token class-name">Autowired</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>data<span class="token punctuation">.</span>mongodb<span class="token punctuation">.</span>core</span><span class="token punctuation">.</span><span class="token class-name">MongoTemplate</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype</span><span class="token punctuation">.</span><span class="token class-name">Component</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">MongoTemplate</span> mongoTemplate<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">MongoTemplate</span> mongoTemplate<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>mongoTemplate <span class="token operator">=</span> mongoTemplate<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x66F4;&#x591A;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x53C2;&#x7167; <a href="https://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/MongoOperations.html" target="_blank"><code>MongoOperations</code></a> Javadoc&#x3002;</p>
<p><a id="boot-features-spring-data-mongo-repositories"></a></p>
<h4 id="3123&#x3001;spring-data-mongodb-&#x8D44;&#x6E90;&#x5E93;">31.2.3&#x3001;Spring Data MongoDB &#x8D44;&#x6E90;&#x5E93;</h4>
<p>Spring Data &#x5305;&#x542B;&#x4E86;&#x5BF9; MongoDB &#x8D44;&#x6E90;&#x5E93;&#xFF08;repository&#xFF09;&#x7684;&#x652F;&#x6301;&#x3002;&#x4E0E;&#x4E4B;&#x524D;&#x8BA8;&#x8BBA;&#x7684; JPA &#x8D44;&#x6E90;&#x5E93;&#x4E00;&#x6837;&#xFF0C;&#x57FA;&#x672C;&#x539F;&#x7406;&#x662F;&#x6839;&#x636E;&#x65B9;&#x6CD5;&#x540D;&#x79F0;&#x81EA;&#x52A8;&#x6784;&#x5EFA;&#x67E5;&#x8BE2;&#x3002;</p>
<p>&#x4E8B;&#x5B9E;&#x4E0A;&#xFF0C;Spring Data JPA &#x548C; Spring Data MongoDB &#x5171;&#x4EAB;&#x901A;&#x7528;&#x7684;&#x5E95;&#x5C42;&#x4EE3;&#x7801;&#xFF0C;&#x56E0;&#x6B64;&#x4F60;&#x53EF;&#x4EE5;&#x62FF;&#x4E4B;&#x524D;&#x63D0;&#x5230;&#x7684; JPA &#x793A;&#x4F8B;&#x4F5C;&#x4E3A;&#x57FA;&#x7840;&#xFF0C;&#x5047;&#x8BBE; <code>City</code> &#x73B0;&#x5728;&#x662F;&#x4E00;&#x4E2A; Mongo &#x6570;&#x636E;&#x7C7B;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x4E00;&#x4E2A; JPA <code>@Entity</code>&#xFF0C;&#x4ED6;&#x4EEC;&#x65B9;&#x5F0F;&#x5DE5;&#x4F5C;&#x76F8;&#x540C;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>example<span class="token punctuation">.</span>myapp<span class="token punctuation">.</span>domain</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>data<span class="token punctuation">.</span>domain</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>data<span class="token punctuation">.</span>repository</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>

<span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">CityRepository</span> <span class="token keyword">extends</span> <span class="token class-name">Repository</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">City</span><span class="token punctuation">,</span> <span class="token class-name">Long</span><span class="token punctuation">&gt;</span></span> <span class="token punctuation">{</span>

    <span class="token class-name">Page</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">City</span><span class="token punctuation">&gt;</span></span> <span class="token function">findAll</span><span class="token punctuation">(</span><span class="token class-name">Pageable</span> pageable<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token class-name">City</span> <span class="token function">findByNameAndStateAllIgnoringCase</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">,</span> <span class="token class-name">String</span> state<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@EntityScan</code> &#x6CE8;&#x89E3;&#x6765;&#x81EA;&#x5B9A;&#x4E49;&#x6587;&#x6863;&#x626B;&#x63CF;&#x4F4D;&#x7F6E;&#x3002;</p>
</blockquote>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6709;&#x5173; Spring Data MongoDB &#x7684;&#x5B8C;&#x6574;&#x8BE6;&#x7EC6;&#x5185;&#x5BB9;&#xFF0C;&#x5305;&#x62EC;&#x5176;&#x4E30;&#x5BCC;&#x7684;&#x5BF9;&#x8C61;&#x5173;&#x7CFB;&#x6620;&#x5C04;&#x6280;&#x672F;&#xFF0C;&#x8BF7;&#x53C2;&#x8003;&#x5176;<a href="https://projects.spring.io/spring-data-mongodb/" target="_blank">&#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-mongo-embedded"></a></p>
<h4 id="3124&#x3001;&#x5185;&#x5D4C;-mongo">31.2.4&#x3001;&#x5185;&#x5D4C; Mongo</h4>
<p>Spring Boot &#x63D0;&#x4F9B;&#x4E86;<a href="https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo" target="_blank">&#x5185;&#x5D4C; Mongo</a> &#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x8981;&#x5728; Spring Boot &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x4F7F;&#x7528;&#x5B83;&#xFF0C;&#x8BF7;&#x6DFB;&#x52A0;&#x4F9D;&#x8D56; <code>de.flapdoodle.embed:de.flapdoodle.embed.mongo</code>&#x3002;</p>
<p>&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.data.mongodb.port</code> &#x5C5E;&#x6027;&#x6765;&#x914D;&#x7F6E; Mongo &#x7684;&#x76D1;&#x542C;&#x7AEF;&#x53E3;&#x3002;&#x5982;&#x679C;&#x60F3;&#x968F;&#x673A;&#x5206;&#x914D;&#x7A7A;&#x95F2;&#x7AEF;&#x53E3;&#xFF0C;&#x8BF7;&#x628A;&#x503C;&#x8BBE;&#x7F6E;&#x4E3A; 0&#x3002;<code>MongoAutoConfiguration</code> &#x521B;&#x5EFA;&#x7684; <code>MongoClient</code> &#x5C06;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x968F;&#x673A;&#x5206;&#x914D;&#x7684;&#x7AEF;&#x53E3;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x4E0D;&#x914D;&#x7F6E;&#x4E00;&#x4E2A;&#x81EA;&#x5B9A;&#x4E49;&#x7AEF;&#x53E3;&#xFF0C;&#x5185;&#x5D4C;&#x652F;&#x6301;&#x5C06;&#x9ED8;&#x8BA4;&#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x968F;&#x673A;&#x7AEF;&#x53E3;&#xFF08;&#x800C;&#x4E0D;&#x662F; 27017&#xFF09;&#x3002;</p>
</blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x7684; classpath &#x4E0A;&#x6709; SLF4J&#xFF0C;Mongo &#x4EA7;&#x751F;&#x7684;&#x8F93;&#x51FA;&#x5C06;&#x81EA;&#x52A8;&#x8DEF;&#x7531;&#x5230;&#x540D;&#x4E3A; <code>org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongo</code> &#x7684; logger&#x3002;</p>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x58F0;&#x660E;&#x81EA;&#x5DF1;&#x7684; <code>IMongodConfig</code> &#x548C; <code>IRuntimeConfig</code> bean &#x6765;&#x63A7;&#x5236; Mongo &#x5B9E;&#x4F8B;&#x7684;&#x914D;&#x7F6E;&#x548C;&#x65E5;&#x5FD7;&#x8DEF;&#x7531;&#x3002;</p>
<p><a id="boot-features-neo4j"></a></p>
<h3 id="313&#x3001;neo4j">31.3&#x3001;Neo4j</h3>
<p><a href="http://neo4j.com/" target="_blank">Neo4j</a> &#x662F;&#x4E00;&#x4E2A;&#x5F00;&#x6E90;&#x7684; NoSQL &#x56FE;&#x5F62;&#x6570;&#x636E;&#x5E93;&#xFF0C;&#x5B83;&#x4F7F;&#x7528;&#x4E86;&#x4E00;&#x4E2A;&#x8282;&#x70B9;&#x7531;&#x5173;&#x7CFB;&#x8FDE;&#x63A5;&#x7684;&#x5BCC;&#x6570;&#x636E;&#x6A21;&#x578B;&#xFF0C;&#x6BD4;&#x4F20;&#x7EDF; RDBMS &#x7684;&#x65B9;&#x5F0F;&#x66F4;&#x9002;&#x5408;&#x8FDE;&#x63A5;&#x5927;&#x6570;&#x636E;&#x3002;Spring Boot &#x4E3A; Neo4j &#x63D0;&#x4F9B;&#x4E86;&#x4FBF;&#x6377;&#x5F15;&#x5165;&#x65B9;&#x5F0F;&#xFF0C;&#x5305;&#x62EC; <code>spring-boot-starter-data-neo4j</code> starter&#x3002;</p>
<p><a id="boot-features-connecting-to-neo4j"></a></p>
<h4 id="3131&#x3001;&#x8FDE;&#x63A5;-neo4j-&#x6570;&#x636E;&#x5E93;">31.3.1&#x3001;&#x8FDE;&#x63A5; Neo4j &#x6570;&#x636E;&#x5E93;</h4>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x50CF;&#x4EFB;&#x4F55; Spring Bean &#x4E00;&#x6837;&#x6CE8;&#x5165;&#x4E00;&#x4E2A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>org.neo4j.ogm.session.Session</code>&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C; &#x8BE5;&#x5B9E;&#x4F8B;&#x5C06;&#x5C1D;&#x8BD5;&#x4F7F;&#x7528;&#x5728; <code>localhost:7687</code> &#x4E0A;&#x4F7F;&#x7528; Bolt &#x534F;&#x8BAE;&#x8FDE;&#x63A5;&#x5230; Neo4j &#x670D;&#x52A1;&#x5668;&#xFF0C;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x6CE8;&#x5165; &#x4E00;&#x4E2A; Neo4j <code>Session</code>&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">Session</span> session<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">Session</span> session<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>session <span class="token operator">=</span> session<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x914D;&#x7F6E; <code>spring.data.neo4j.*</code> &#x5C5E;&#x6027;&#x6765;&#x8BBE;&#x7F6E; uri &#x548C;&#x51ED;&#x636E;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.data.neo4j.uri</span><span class="token attr-value"><span class="token punctuation">=</span>bolt://my-server:7687</span>
<span class="token constant">spring.data.neo4j.username</span><span class="token attr-value"><span class="token punctuation">=</span>neo4j</span>
<span class="token constant">spring.data.neo4j.password</span><span class="token attr-value"><span class="token punctuation">=</span>secret</span>
</code></pre>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6DFB;&#x52A0;&#x81EA;&#x5DF1;&#x7684; <code>org.neo4j.ogm.config.Configuration</code> @Bean &#x6765;&#x5B8C;&#x5168;&#x63A7;&#x5236; session &#x521B;&#x5EFA;&#x3002;&#x6B64;&#x5916;&#xFF0C;&#x6DFB;&#x52A0; <code>SessionFactory</code> &#x7C7B;&#x578B;&#x7684; @Bean &#x4F1A;&#x7981;&#x7528;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x56E0;&#x6B64;&#x60A8;&#x53EF;&#x4EE5;&#x638C;&#x63A7;&#x6240;&#x6709;&#x3002;</p>
<p><a id="boot-features-connecting-to-neo4j-embedded"></a></p>
<h4 id="3132&#x3001;&#x4F7F;&#x7528;&#x5185;&#x5D4C;&#x6A21;&#x5F0F;">31.3.2&#x3001;&#x4F7F;&#x7528;&#x5185;&#x5D4C;&#x6A21;&#x5F0F;</h4>
<p>&#x5982;&#x679C;&#x60A8;&#x5C06; <code>org.neo4j:neo4j-ogm-embedded-driver</code> &#x6DFB;&#x52A0;&#x5230;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x4F9D;&#x8D56;&#x4E2D;&#xFF0C;Spring Boot &#x5C06;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A;&#x8FDB;&#x7A0B;&#x5185;&#x5185;&#x5D4C;&#x7684; Neo4j &#x5B9E;&#x4F8B;&#xFF0C;&#x5F53;&#x60A8;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5173;&#x95ED;&#x65F6;&#xFF0C;&#x8BE5;&#x5B9E;&#x4F8B;&#x5C06;&#x4E0D;&#x4F1A;&#x4FDD;&#x7559;&#x4EFB;&#x4F55;&#x6570;&#x636E;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5185;&#x5D4C; Neo4j OGM &#x9A71;&#x52A8;&#x672C;&#x8EAB;&#x4E0D;&#x63D0;&#x4F9B; Neo4j &#x60A8;&#x5FC5;&#x987B;&#x81EA;&#x5DF1;&#x58F0;&#x660E; <code>org.neo4j:neo4j</code> &#x4F9D;&#x8D56;&#xFF0C;&#x8BF7;&#x53C2;&#x8003; <a href="https://neo4j.com/docs/ogm-manual/current/reference/#reference:getting-started" target="_blank">Neo4j OGM &#x6587;&#x6863;</a> &#x83B7;&#x53D6;&#x517C;&#x5BB9;&#x7248;&#x672C;&#x5217;&#x8868;&#x3002;</p>
</blockquote>
<p>&#x5F53; classpath &#x4E0A;&#x6709;&#x591A;&#x4E2A;&#x9A71;&#x52A8;&#x65F6;&#xFF0C;&#x5185;&#x5D4C;&#x9A71;&#x52A8;&#x4F18;&#x5148;&#x4E8E;&#x5176;&#x4ED6;&#x9A71;&#x52A8;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>spring.data.neo4j.embedded.enabled=false</code> &#x6765;&#x663E;&#x5F0F;&#x7981;&#x7528;&#x5185;&#x5D4C;&#x6A21;&#x5F0F;&#x3002;</p>
<p>&#x5982;&#x679C;&#x5185;&#x5D4C;&#x9A71;&#x52A8;&#x548C; Neo4j &#x5185;&#x6838;&#x5982;&#x4E0A;&#x6240;&#x8FF0;&#x4F4D;&#x4E8E; classpath &#x4E0A;&#xFF0C;&#x5219; <a href="#boot-features-testing-spring-boot-applications-testing-autoconfigured-neo4j-test">Data Neo4j &#x6D4B;&#x8BD5;</a> &#x4F1A;&#x81EA;&#x52A8;&#x4F7F;&#x7528;&#x5185;&#x5D4C; Neo4j &#x5B9E;&#x4F8B;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5728;&#x914D;&#x7F6E;&#x4E2D;&#x63D0;&#x4F9B;&#x6570;&#x636E;&#x5E93;&#x6587;&#x4EF6;&#x8DEF;&#x5F84;&#x6765;&#x4E3A;&#x5185;&#x5D4C;&#x6A21;&#x5F0F;&#x542F;&#x7528;&#x6301;&#x4E45;&#x5316;&#xFF0C;&#x4F8B;&#x5982;&#xFF1A;<code>spring.data.neo4j.uri=file://var/tmp/graph.db</code>&#x3002;</p>
</blockquote>
<p><a id="boot-features-neo4j-ogm-session"></a></p>
<h4 id="3133&#x3001;neo4jsession">31.3.3&#x3001;Neo4jSession</h4>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x6B63;&#x5728;&#x8FD0;&#x884C; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;&#x4F1A;&#x8BDD;&#xFF08;session&#xFF09;&#x5C06;&#x88AB;&#x7ED1;&#x5B9A;&#x5230;&#x5F53;&#x524D;&#x8BF7;&#x6C42;&#x7684;&#x6574;&#x4E2A;&#x5904;&#x7406;&#x7EBF;&#x7A0B;&#xFF08;&#x5373; <strong>Open Session in View</strong> &#x6A21;&#x5F0F;&#xFF09;&#x3002;&#x5982;&#x679C;&#x4E0D;&#x5E0C;&#x671B;&#x6B64;&#x884C;&#x4E3A;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>application.properties</code> &#x4E2D;&#x6DFB;&#x52A0;&#x4EE5;&#x4E0B;&#x5185;&#x5BB9;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.data.neo4j.open-in-view</span><span class="token attr-value"><span class="token punctuation">=</span>false</span>
</code></pre>
<p><a id="boot-features-spring-data-neo4j-repositories"></a></p>
<h4 id="3134&#x3001;spring-data-neo4j-&#x8D44;&#x6E90;&#x5E93;">31.3.4&#x3001;Spring Data Neo4j &#x8D44;&#x6E90;&#x5E93;</h4>
<p>Spring Data &#x5305;&#x62EC;&#x4E86;&#x5BF9; Neo4j &#x8D44;&#x6E90;&#x5E93;&#x7684;&#x652F;&#x6301;&#x3002;</p>
<p>Spring Data Neo4j &#x4E0E; Spring Data JPA &#x5171;&#x4EAB;&#x76F8;&#x540C;&#x7684;&#x901A;&#x7528;&#x5E95;&#x5C42;&#x4EE3;&#x7801;&#xFF0C;&#x56E0;&#x6B64;&#x60A8;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x628A;&#x4E4B;&#x524D;&#x7684; JPA &#x793A;&#x4F8B;&#x4F5C;&#x4E3A;&#x57FA;&#x7840;&#xFF0C;&#x5047;&#x8BBE; <code>City</code> &#x73B0;&#x5728;&#x662F;&#x4E00;&#x4E2A; Neo4j OGM <code>@NodeEntity</code>&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x4E00;&#x4E2A; JPA <code>@Entity</code>&#xFF0C;&#x5E76;&#x4E14;&#x8D44;&#x6E90;&#x5E93;&#x62BD;&#x8C61;&#x4EE5;&#x76F8;&#x540C;&#x7684;&#x65B9;&#x5F0F;&#x5DE5;&#x4F5C;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">package</span> <span class="token namespace">com<span class="token punctuation">.</span>example<span class="token punctuation">.</span>myapp<span class="token punctuation">.</span>domain</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">java<span class="token punctuation">.</span>util</span><span class="token punctuation">.</span><span class="token class-name">Optional</span><span class="token punctuation">;</span>

<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>data<span class="token punctuation">.</span>neo4j<span class="token punctuation">.</span>repository</span><span class="token punctuation">.</span>*<span class="token punctuation">;</span>

<span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">CityRepository</span> <span class="token keyword">extends</span> <span class="token class-name">Neo4jRepository</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">City</span><span class="token punctuation">,</span> <span class="token class-name">Long</span><span class="token punctuation">&gt;</span></span> <span class="token punctuation">{</span>

    <span class="token class-name">Optional</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">City</span><span class="token punctuation">&gt;</span></span> <span class="token function">findOneByNameAndState</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">,</span> <span class="token class-name">String</span> state<span class="token punctuation">)</span><span class="token punctuation">;</span>

<span class="token punctuation">}</span>
</code></pre>
<p><code>spring-boot-starter-data-neo4j</code> starter &#x652F;&#x6301;&#x8D44;&#x6E90;&#x5E93;&#x548C;&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>@Configuration</code> bean &#x4E0A;&#x5206;&#x522B;&#x4F7F;&#x7528; <code>@EnableNeo4jRepositories</code> &#x548C; <code>@EntityScan</code> &#x6765;&#x81EA;&#x5B9A;&#x4E49;&#x4F4D;&#x7F6E;&#x4EE5;&#x67E5;&#x627E;&#x8D44;&#x6E90;&#x5E93;&#x548C;&#x5B9E;&#x4F53;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<p>&#x6709;&#x5173; Spring Data Neo4j &#x7684;&#x5B8C;&#x6574;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x5305;&#x62EC;&#x5176;&#x5BF9;&#x8C61;&#x6620;&#x5C04;&#x6280;&#x672F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605;<a href="https://projects.spring.io/spring-data-neo4j/" target="_blank">&#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x3002;</p>
<p><a id="boot-features-gemfire"></a></p>
<h3 id="314&#x3001;gemfire">31.4&#x3001;Gemfire</h3>
<p><a href="https://github.com/spring-projects/spring-data-gemfire" target="_blank">Spring Data Gemfire</a> &#x63D0;&#x4F9B;&#x4E86;&#x4FBF;&#x6377;&#x7684; Spring &#x6574;&#x5408;&#x5DE5;&#x5177;&#xFF0C;&#x7528;&#x4E8E;&#x8BBF;&#x95EE; <a href="https://pivotal.io/big-data/pivotal-gemfire#details" target="_blank">Pivotal Gemfire</a> &#x6570;&#x636E;&#x7BA1;&#x7406;&#x5E73;&#x53F0;&#x3002;        <code>spring-boot-starter-data-gemfire</code> starter &#x5305;&#x542B;&#x4E86;&#x76F8;&#x5173;&#x4F9D;&#x8D56;&#x3002;&#x76EE;&#x524D;&#x6CA1;&#x6709;&#x9488;&#x5BF9; Gemfire &#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x652F;&#x6301;&#xFF0C;&#x4F46;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4E00;&#x4E2A;<a href="https://github.com/spring-projects/spring-data-gemfire/blob/master/src/main/java/org/springframework/data/gemfire/repository/config/EnableGemfireRepositories.java" target="_blank">&#x5355;&#x72EC;&#x7684;&#x6CE8;&#x89E3;&#xFF08;@EnableGemfireRepositories&#xFF09;</a>&#x6765;&#x542F;&#x7528; Spring Data &#x8D44;&#x6E90;&#x5E93;&#x3002;</p>
<p><a id="boot-features-solr"></a></p>
<h3 id="315&#x3001;solr">31.5&#x3001;Solr</h3>
<p><a href="https://lucene.apache.org/solr/" target="_blank">Apache Solr</a> &#x662F;&#x4E00;&#x4E2A;&#x641C;&#x7D20;&#x5F15;&#x64CE;&#x3002;Spring Boot &#x4E3A; Solr 5 &#x5BA2;&#x6237;&#x7AEF;&#x7C7B;&#x5E93;&#x63D0;&#x4F9B;&#x4E86;&#x57FA;&#x672C;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x5E76;&#x4E14; <a href="https://github.com/spring-projects/spring-data-solr" target="_blank">Spring Data Solr</a> &#x4E3A;&#x5176;&#x63D0;&#x4F9B;&#x7ED9;&#x4E86;&#x9876;&#x5C42;&#x62BD;&#x8C61;&#x3002;&#x76F8;&#x5173;&#x7684;&#x4F9D;&#x8D56;&#x5305;&#x542B;&#x5728;&#x4E86; <code>spring-boot-starter-data-solr</code> starter &#x4E2D;&#x3002;</p>
<p><a id="boot-features-solr"></a></p>
<h4 id="3151&#x3001;&#x8FDE;&#x63A5;-solr">31.5.1&#x3001;&#x8FDE;&#x63A5; Solr</h4>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x50CF;&#x5176;&#x4ED6; Spring Bean &#x4E00;&#x6837;&#x6CE8;&#x5165;&#x4E00;&#x4E2A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>SolrClient</code> &#x5B9E;&#x4F8B;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x8BE5;&#x5B9E;&#x4F8B;&#x5C06;&#x5C1D;&#x8BD5;&#x901A;&#x8FC7; <a href="http://localhost:8983/solr" target="_blank"><code>localhost:8983/solr</code></a> &#x8FDE;&#x63A5;&#x5230;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x6CE8;&#x5165;&#x4E00;&#x4E2A; Solr bean&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token class-name">SolrClient</span> solr<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">SolrClient</span> solr<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>solr <span class="token operator">=</span> solr<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x5982;&#x679C;&#x60A8;&#x6DFB;&#x52A0;&#x4E86;&#x81EA;&#x5DF1;&#x7684; <code>SolrClient</code> &#x7C7B;&#x578B;&#x7684; <code>@Bean</code>&#xFF0C;&#x5B83;&#x5C06;&#x66FF;&#x6362;&#x6389;&#x9ED8;&#x8BA4;&#x914D;&#x7F6E;&#x3002;</p>
<p><a id="boot-features-spring-data-solr-repositories"></a></p>
<h4 id="3152&#x3001;spring-data-solr-&#x8D44;&#x6E90;&#x5E93;">31.5.2&#x3001;Spring Data Solr &#x8D44;&#x6E90;&#x5E93;</h4>
<p>Spring Data &#x5305;&#x542B;&#x4E86;&#x5BF9; Apache Solr &#x8D44;&#x6E90;&#x5E93;&#x7684;&#x652F;&#x6301;&#x3002;&#x4E0E;&#x4E4B;&#x524D;&#x8BA8;&#x8BBA;&#x7684; JPA &#x8D44;&#x6E90;&#x5E93;&#x4E00;&#x6837;&#xFF0C;&#x57FA;&#x672C;&#x539F;&#x7406;&#x662F;&#x6839;&#x636E;&#x65B9;&#x6CD5;&#x540D;&#x79F0;&#x81EA;&#x52A8;&#x6784;&#x9020;&#x67E5;&#x8BE2;&#x3002;</p>
<p>&#x4E8B;&#x5B9E;&#x4E0A;&#xFF0C;Spring Data JPA &#x548C; Spring Data Solr &#x5171;&#x4EAB;&#x4E86;&#x76F8;&#x540C;&#x7684;&#x901A;&#x7528;&#x5E95;&#x5C42;&#x4EE3;&#x7801;&#xFF0C;&#x56E0;&#x6B64;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4E4B;&#x524D;&#x7684; JPA &#x793A;&#x4F8B;&#x4F5C;&#x4E3A;&#x57FA;&#x7840;&#xFF0C;&#x5047;&#x8BBE; <code>City</code> &#x73B0;&#x5728;&#x662F;&#x4E00;&#x4E2A; <code>@SolrDocument</code> &#x7C7B;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x4E00;&#x4E2A; JPA <code>@Entity</code>&#xFF0C;&#x5B83;&#x7684;&#x5DE5;&#x4F5C;&#x65B9;&#x5F0F;&#x76F8;&#x540C;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6709;&#x5173; Spring Data Solr &#x7684;&#x5B8C;&#x6574;&#x8BE6;&#x7EC6;&#x5185;&#x5BB9;&#xFF0C;&#x8BF7;&#x53C2;&#x8003;&#x5176;<a href="https://projects.spring.io/spring-data-solr/" target="_blank">&#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-elasticsearch"></a></p>
<h3 id="316&#x3001;elasticsearch">31.6&#x3001;Elasticsearch</h3>
<p><a href="https://www.elastic.co/products/elasticsearch" target="_blank">Elasticsearch</a> &#x662F;&#x4E00;&#x4E2A;&#x5F00;&#x6E90;&#x3001;&#x5206;&#x5E03;&#x5F0F;&#x3001;RESTful &#x7684;&#x5B9E;&#x65F6;&#x641C;&#x7D22;&#x5206;&#x6790;&#x5F15;&#x64CE;&#x3002;Spring Boot &#x4E3A; Elasticsearch &#x63D0;&#x4F9B;&#x4E86;&#x57FA;&#x672C;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;</p>
<p>Spring Boot &#x652F;&#x6301;&#x4EE5;&#x4E0B; HTTP &#x5BA2;&#x6237;&#x7AEF;&#xFF1A;</p>
<ul>
<li>&#x5B98;&#x65B9; Java <strong>Low Level&#xFF08;&#x4F4E;&#x7EA7;&#xFF09;</strong> &#x548C; <strong>High Level&#xFF08;&#x9AD8;&#x7EA7;&#xFF09;</strong> REST &#x5BA2;&#x6237;&#x7AEF;</li>
<li><a href="https://github.com/searchbox-io/Jest" target="_blank">Jest</a></li>
</ul>
<p><a href="https://github.com/spring-projects/spring-data-elasticsearch" target="_blank">Spring Data Elasticsearch</a> &#x4F9D;&#x65E7;&#x4F7F;&#x7528;&#x4F20;&#x8F93;&#x5BA2;&#x6237;&#x7AEF;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring-boot-starter-data-elasticsearch</code> starter &#x5F15;&#x5165;&#x4F7F;&#x7528;&#x5B83;&#x3002;</p>
<p><a id="boot-features-connecting-to-elasticsearch-rest"></a></p>
<h4 id="3161&#x3001;&#x4F7F;&#x7528;-rest-&#x5BA2;&#x6237;&#x7AEF;&#x8FDE;&#x63A5;-elasticsearch">31.6.1&#x3001;&#x4F7F;&#x7528; REST &#x5BA2;&#x6237;&#x7AEF;&#x8FDE;&#x63A5; Elasticsearch</h4>
<p>Elasticsearch &#x63D0;&#x4F9B;&#x4E86;&#x4E24;&#x4E2A;&#x53EF;&#x7528;&#x4E8E;&#x67E5;&#x8BE2;&#x96C6;&#x7FA4;&#x7684; <a href="https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/index.html" target="_blank">REST &#x5BA2;&#x6237;&#x7AEF;</a>&#xFF1A;<strong>Low Level&#xFF08;&#x4F4E;&#x7EA7;&#xFF09;</strong> &#x548C; <strong>High Level&#xFF08;&#x9AD8;&#x7EA7;&#xFF09;</strong>&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x7684; classpath &#x4E0A;&#x5B58;&#x5728; <code>org.elasticsearch.client:elasticsearch-rest-client</code> &#x4F9D;&#x8D56;&#xFF0C;&#x5219; Spring Boot &#x5C06;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x5E76;&#x6CE8;&#x518C;&#x9ED8;&#x8BA4;&#x76EE;&#x6807;&#x4E3A; <a href="http://localhost:9200/" target="_blank"><code>localhost:9200</code></a> &#x7684; <code>RestClient</code> bean&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x8FDB;&#x4E00;&#x6B65;&#x8C03;&#x6574; <code>RestClient</code> &#x7684;&#x914D;&#x7F6E;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.elasticsearch.rest.uris</span><span class="token attr-value"><span class="token punctuation">=</span>http://search.example.com:9200</span>
<span class="token constant">spring.elasticsearch.rest.username</span><span class="token attr-value"><span class="token punctuation">=</span>user</span>
<span class="token constant">spring.elasticsearch.rest.password</span><span class="token attr-value"><span class="token punctuation">=</span>secret</span>
</code></pre>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x6CE8;&#x518C;&#x5B9E;&#x73B0;&#x4EFB;&#x610F;&#x6570;&#x91CF;&#x7684; <code>RestClientBuilderCustomizer</code> bean&#xFF0C;&#x4EE5;&#x8FDB;&#x884C;&#x66F4;&#x9AD8;&#x7EA7;&#x7684;&#x81EA;&#x5B9A;&#x4E49;&#x3002;&#x8981;&#x5B8C;&#x5168;&#x63A7;&#x5236;&#x6CE8;&#x518C;&#x6D41;&#x7A0B;&#xFF0C;&#x8BF7;&#x5B9A;&#x4E49; <code>RestClient</code> bean&#x3002;</p>
<p>&#x5982;&#x679C;&#x4F60; classpath &#x4E0A;&#x6709; <code>org.elasticsearch.client:elasticsearch-rest-high-level-client</code> &#x4F9D;&#x8D56;&#xFF0C;Spring Boot &#x5C06;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A; <code>RestHighLevelClient</code>&#xFF0C;&#x5B83;&#x5305;&#x88C5;&#x4E86;&#x6240;&#x6709;&#x73B0;&#x6709;&#x7684; <code>RestClient</code> bean&#xFF0C;&#x91CD;&#x7528;&#x5176; HTTP &#x914D;&#x7F6E;&#x3002;</p>
<p><a id="boot-features-connecting-to-elasticsearch-jest"></a></p>
<h4 id="3162&#x3001;&#x4F7F;&#x7528;-jest-&#x8FDE;&#x63A5;-elasticsearch">31.6.2&#x3001;&#x4F7F;&#x7528; Jest &#x8FDE;&#x63A5; Elasticsearch</h4>
<p>&#x5982;&#x679C;&#x60A8;&#x7684; classpath &#x4E0A;&#x5B58;&#x5728; <code>Jest</code>&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x6CE8;&#x5165;&#x4E00;&#x4E2A;&#x9ED8;&#x8BA4;&#x76EE;&#x6807;&#x4E3A; <a href="http://localhost:9200/" target="_blank"><code>localhost:9200</code></a> &#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E; <code>JestClient</code>&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x8FDB;&#x4E00;&#x6B65;&#x8C03;&#x6574;&#x5BA2;&#x6237;&#x7AEF;&#x914D;&#x7F6E;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.elasticsearch.jest.uris</span><span class="token attr-value"><span class="token punctuation">=</span>http://search.example.com:9200</span>
<span class="token constant">spring.elasticsearch.jest.read-timeout</span><span class="token attr-value"><span class="token punctuation">=</span>10000</span>
<span class="token constant">spring.elasticsearch.jest.username</span><span class="token attr-value"><span class="token punctuation">=</span>user</span>
<span class="token constant">spring.elasticsearch.jest.password</span><span class="token attr-value"><span class="token punctuation">=</span>secret</span>
</code></pre>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x6CE8;&#x518C;&#x4EFB;&#x4F55;&#x6570;&#x91CF;&#x5B9E;&#x73B0;&#x4E86; <code>HttpClientConfigBuilderCustomizer</code> &#x7684; bean&#xFF0C;&#x4EE5;&#x8FDB;&#x884C;&#x66F4;&#x52A0;&#x9AD8;&#x7EA7;&#x7684;&#x81EA;&#x5B9A;&#x4E49;&#x3002;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x8C03;&#x6574;&#x4E86;&#x5176;&#x4ED6; HTTP &#x8BBE;&#x7F6E;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">HttpSettingsCustomizer</span> <span class="token keyword">implements</span> <span class="token class-name">HttpClientConfigBuilderCustomizer</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">customize</span><span class="token punctuation">(</span><span class="token class-name">HttpClientConfig</span><span class="token punctuation">.</span><span class="token class-name">Builder</span> builder<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        builder<span class="token punctuation">.</span><span class="token function">maxTotalConnection</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">defaultMaxTotalConnectionPerRoute</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x8981;&#x5B8C;&#x5168;&#x63A7;&#x5236;&#x6CE8;&#x518C;&#x6D41;&#x7A0B;&#xFF0C;&#x8BF7;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A; <code>JestClient</code> bean&#x3002;</p>
<p><a id="boot-features-connecting-to-elasticsearch-spring-data"></a></p>
<h4 id="3163&#x3001;&#x4F7F;&#x7528;-spring-data-&#x8FDE;&#x63A5;-elasticsearch">31.6.3&#x3001;&#x4F7F;&#x7528; Spring Data &#x8FDE;&#x63A5; Elasticsearch</h4>
<p>&#x8981;&#x8FDE;&#x63A5; Elasticsearch&#xFF0C;&#x60A8;&#x5FC5;&#x987B;&#x63D0;&#x4F9B;&#x4E00;&#x4E2A;&#x6216;&#x591A;&#x4E2A;&#x7FA4;&#x96C6;&#x8282;&#x70B9;&#x7684;&#x5730;&#x5740;&#x3002;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5C06; <code>spring.data.elasticsearch.cluster-nodes</code> &#x5C5E;&#x6027;&#x8BBE;&#x7F6E;&#x4E3A;&#x4EE5;&#x9017;&#x53F7;&#x5206;&#x9694;&#x7684; <code>host:port</code> &#x5217;&#x8868;&#x6765;&#x6307;&#x5B9A;&#x5730;&#x5740;&#x3002;&#x4F7F;&#x7528;&#x6B64;&#x914D;&#x7F6E;&#xFF0C;&#x53EF;&#x4EE5;&#x50CF;&#x5176;&#x4ED6; Spring bean &#x4E00;&#x6837;&#x6CE8;&#x5165; <code>ElasticsearchTemplate</code> &#x6216; <code>TransportClient</code>&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">ElasticsearchTemplate</span> template<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">ElasticsearchTemplate</span> template<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>template <span class="token operator">=</span> template<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x5982;&#x679C;&#x60A8;&#x6DFB;&#x52A0;&#x4E86;&#x81EA;&#x5DF1;&#x7684; <code>ElasticsearchTemplate</code> &#x6216;&#x8005; <code>TransportClient</code> <code>@Bean</code>&#xFF0C;&#x5219;&#x5176;&#x5C06;&#x66FF;&#x4EE3;&#x9ED8;&#x8BA4;&#x914D;&#x7F6E;&#x3002;</p>
<p><a id="boot-features-spring-data-elasticsearch-repositories"></a></p>
<h4 id="3164&#x3001;spring-data-elasticsearch-&#x8D44;&#x6E90;&#x5E93;">31.6.4&#x3001;Spring Data Elasticsearch &#x8D44;&#x6E90;&#x5E93;</h4>
<p>Spring Data &#x5305;&#x542B;&#x4E86;&#x5BF9; Elasticsearch &#x8D44;&#x6E90;&#x5E93;&#x7684;&#x652F;&#x6301;&#xFF0C;&#x4E0E;&#x4E4B;&#x524D;&#x8BA8;&#x8BBA;&#x7684; JPA &#x8D44;&#x6E90;&#x5E93;&#x4E00;&#x6837;&#xFF0C;&#x5176;&#x539F;&#x7406;&#x662F;&#x6839;&#x636E;&#x65B9;&#x6CD5;&#x540D;&#x79F0;&#x81EA;&#x52A8;&#x6784;&#x9020;&#x67E5;&#x8BE2;&#x3002;</p>
<p>&#x4E8B;&#x5B9E;&#x4E0A;&#xFF0C;Spring Data JPA &#x4E0E; Spring Data Elasticsearch &#x5171;&#x4EAB;&#x4E86;&#x76F8;&#x540C;&#x7684;&#x901A;&#x7528;&#x5E95;&#x5C42;&#x4EE3;&#x7801;&#xFF0C;&#x56E0;&#x6B64;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x4E4B;&#x524D;&#x7684; JPA &#x793A;&#x4F8B;&#x4F5C;&#x4E3A;&#x57FA;&#x7840;&#xFF0C;&#x5047;&#x8BBE; <code>City</code> &#x6B64;&#x65F6;&#x662F;&#x4E00;&#x4E2A; Elasticsearch <code>@Document</code> &#x7C7B;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x4E00;&#x4E2A; JPA <code>@Entity</code>&#xFF0C;&#x5B83;&#x4EE5;&#x76F8;&#x540C;&#x7684;&#x65B9;&#x5F0F;&#x5DE5;&#x4F5C;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6709;&#x5173; Spring Data Elasticsearch &#x7684;&#x5B8C;&#x6574;&#x8BE6;&#x7EC6;&#x5185;&#x5BB9;&#xFF0C;&#x8BF7;&#x53C2;&#x9605;&#x5176;<a href="https://docs.spring.io/spring-data/elasticsearch/docs/" target="_blank">&#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-cassandra"></a></p>
<h3 id="317&#x3001;cassandra">31.7&#x3001;Cassandra</h3>
<p><a href="https://cassandra.apache.org/" target="_blank">Cassandra</a> &#x662F;&#x4E00;&#x4E2A;&#x5F00;&#x6E90;&#x7684;&#x5206;&#x5E03;&#x5F0F;&#x6570;&#x636E;&#x5E93;&#x7BA1;&#x7406;&#x7CFB;&#x7EDF;&#xFF0C;&#x65E8;&#x5728;&#x5904;&#x7406;&#x5546;&#x7528;&#x670D;&#x52A1;&#x5668;&#x4E0A;&#x7684;&#x5927;&#x91CF;&#x6570;&#x636E;&#x3002;Spring Boot &#x4E3A; Cassandra &#x63D0;&#x4F9B;&#x4E86;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x4E14; <a href="https://github.com/spring-projects/spring-data-cassandra" target="_blank">Spring Data Cassandra</a> &#x4E3A;&#x5176;&#x63D0;&#x4F9B;&#x4E86;&#x9876;&#x5C42;&#x62BD;&#x8C61;&#x3002;&#x76F8;&#x5173;&#x4F9D;&#x8D56;&#x5305;&#x542B;&#x5728; <code>spring-boot-starter-data-cassandra</code> starter &#x4E2D;&#x3002;</p>
<p><a id="boot-features-connecting-to-cassandra"></a></p>
<h4 id="3171&#x3001;&#x8FDE;&#x63A5;-cassandra">31.7.1&#x3001;&#x8FDE;&#x63A5; Cassandra</h4>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x50CF;&#x5176;&#x4ED6; Spring Bean &#x4E00;&#x6837;&#x6CE8;&#x5165;&#x4E00;&#x4E2A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>CassandraTemplate</code> &#x6216; Cassandra <code>Session</code> &#x5B9E;&#x4F8B;&#x3002;<code>spring.data.cassandra.*</code> &#x5C5E;&#x6027;&#x53EF;&#x7528;&#x4E8E;&#x81EA;&#x5B9A;&#x4E49;&#x8FDE;&#x63A5;&#x3002;&#x901A;&#x5E38;&#xFF0C;&#x60A8;&#x4F1A;&#x63D0;&#x4F9B; <code>keyspace-name</code> &#x548C; <code>contact-points</code>&#x5C5E;&#x6027;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.data.cassandra.keyspace-name</span><span class="token attr-value"><span class="token punctuation">=</span>mykeyspace</span>
<span class="token constant">spring.data.cassandra.contact-points</span><span class="token attr-value"><span class="token punctuation">=</span>cassandrahost1,cassandrahost2</span>
</code></pre>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x6CE8;&#x518C;&#x4EFB;&#x610F;&#x6570;&#x91CF;&#x5B9E;&#x73B0;&#x4E86; ClusterBuilderCustomizer &#x7684; bean&#xFF0C;&#x4EE5;&#x8FDB;&#x884C;&#x66F4;&#x9AD8;&#x7EA7;&#x7684;&#x81EA;&#x5B9A;&#x4E49;&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x6CE8;&#x5165;&#x4E00;&#x4E2A; Cassandra bean&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token class-name">CassandraTemplate</span> template<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">CassandraTemplate</span> template<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>template <span class="token operator">=</span> template<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x5982;&#x679C;&#x60A8;&#x6DFB;&#x52A0;&#x4E86;&#x81EA;&#x5DF1;&#x7684;&#x7C7B;&#x7684;&#x4E3A; <code>@CassandraTemplate</code> &#x7684; <code>@Bean</code>&#xFF0C;&#x5219;&#x5176;&#x5C06;&#x66FF;&#x4EE3;&#x9ED8;&#x8BA4;&#x503C;&#x3002;</p>
<p><a id="boot-features-spring-data-cassandra-repositories"></a></p>
<h4 id="3172&#x3001;spring-data-cassandra-&#x8D44;&#x6E90;&#x5E93;">31.7.2&#x3001;Spring Data Cassandra &#x8D44;&#x6E90;&#x5E93;</h4>
<p>Spring Data &#x5305;&#x542B;&#x4E86;&#x57FA;&#x672C;&#x7684; Cassandra &#x8D44;&#x6E90;&#x5E93;&#x652F;&#x6301;&#x3002;&#x76EE;&#x524D;&#xFF0C;&#x5176;&#x9650;&#x5236;&#x8981;&#x6BD4;&#x4E4B;&#x524D;&#x8BA8;&#x8BBA;&#x7684; JPA &#x8D44;&#x6E90;&#x5E93;&#x8981;&#x591A;&#xFF0C;&#x5E76;&#x4E14;&#x9700;&#x8981;&#x5728; finder &#x65B9;&#x6CD5;&#x4E0A;&#x4F7F;&#x7528; <code>@Query</code> &#x6CE8;&#x89E3;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6709;&#x5173; Spring Data Cassandra &#x7684;&#x5B8C;&#x6574;&#x8BE6;&#x7EC6;&#x5185;&#x5BB9;&#xFF0C;&#x8BF7;&#x53C2;&#x9605;&#x5176;<a href="https://docs.spring.io/spring-data/cassandra/docs/" target="_blank">&#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-couchbase"></a></p>
<h3 id="318&#x3001;couchbase">31.8&#x3001;Couchbase</h3>
<p><a href="https://www.couchbase.com/" target="_blank">Couchbase</a> &#x662F;&#x4E00;&#x4E2A;&#x5F00;&#x6E90;&#x3001;&#x5206;&#x5E03;&#x5F0F;&#x591A;&#x6A21;&#x578B;&#x7684; NoSQL &#x9762;&#x5411;&#x6587;&#x6863;&#x6570;&#x636E;&#x5E93;&#xFF0C;&#x5176;&#x9488;&#x5BF9;&#x4EA4;&#x4E92;&#x5F0F;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x505A;&#x4E86;&#x4F18;&#x5316;&#x3002;Spring Boot &#x4E3A; Couchbase &#x63D0;&#x4F9B;&#x4E86;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x4E14; <a href="https://github.com/spring-projects/spring-data-couchbase" target="_blank">Spring Data Couchbase</a> &#x4E3A;&#x5176;&#x63D0;&#x4F9B;&#x4E86;&#x9876;&#x5C42;&#x62BD;&#x8C61;&#x3002;&#x76F8;&#x5173;&#x7684;&#x4F9D;&#x8D56;&#x5305;&#x542B;&#x5728;&#x4E86; <code>spring-boot-starter-data-couchbase</code> starter &#x4E2D;&#x3002;</p>
<p><a id="boot-features-connecting-to-couchbase"></a></p>
<h4 id="3181&#x3001;&#x8FDE;&#x63A5;-couchbase">31.8.1&#x3001;&#x8FDE;&#x63A5; Couchbase</h4>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6DFB;&#x52A0; Couchbase SDK &#x548C;&#x4E00;&#x4E9B;&#x914D;&#x7F6E;&#x6765;&#x8F7B;&#x677E;&#x83B7;&#x53D6; <code>Bucket</code> &#x548C; <code>Cluster</code>&#x3002;<code>spring.couchbase.*</code> &#x5C5E;&#x6027;&#x53EF;&#x7528;&#x4E8E;&#x81EA;&#x5B9A;&#x4E49;&#x8FDE;&#x63A5;&#x3002;&#x901A;&#x5E38;&#x60A8;&#x4F1A;&#x914D;&#x7F6E; bootstrap host&#x3001;bucket name &#x548C; password&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.couchbase.bootstrap-hosts</span><span class="token attr-value"><span class="token punctuation">=</span>my-host-1,192.168.1.123</span>
<span class="token constant">spring.couchbase.bucket.name</span><span class="token attr-value"><span class="token punctuation">=</span>my-bucket</span>
<span class="token constant">spring.couchbase.bucket.password</span><span class="token attr-value"><span class="token punctuation">=</span>secret</span>
</code></pre>
<blockquote>
<p>&#x60A8;<strong>&#x81F3;&#x5C11;</strong>&#x9700;&#x8981;&#x63D0;&#x4F9B; bootstrap host&#xFF0C;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;bucket name &#x4E3A; <code>default</code> &#x4E14; password &#x4E3A;&#x7A7A;&#x5B57;&#x7B26;&#x4E32;&#x3002;&#x6216;&#x8005;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5B9A;&#x4E49;&#x81EA;&#x5DF1;&#x7684; <code>org.springframework.data.couchbase.config.CouchbaseConfigurer</code> @Bean &#x6765;&#x63A7;&#x5236;&#x6574;&#x4E2A;&#x914D;&#x7F6E;&#x3002;</p>
</blockquote>
<p>&#x4E5F;&#x53EF;&#x4EE5;&#x81EA;&#x5B9A;&#x4E49;&#x4E00;&#x4E9B; <code>CouchbaseEnvironment</code> &#x8BBE;&#x7F6E;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x4EE5;&#x4E0B;&#x914D;&#x7F6E;&#x4FEE;&#x6539;&#x4E86;&#x6253;&#x5F00;&#x4E00;&#x4E2A;&#x65B0; <code>Bucket</code> &#x7684;&#x8D85;&#x65F6;&#x65F6;&#x95F4;&#x548C;&#x5F00;&#x542F;&#x4E86; SSL &#x652F;&#x6301;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.couchbase.env.timeouts.connect</span><span class="token attr-value"><span class="token punctuation">=</span>3000</span>
<span class="token constant">spring.couchbase.env.ssl.key-store</span><span class="token attr-value"><span class="token punctuation">=</span>/location/of/keystore.jks</span>
<span class="token constant">spring.couchbase.env.ssl.key-store-password</span><span class="token attr-value"><span class="token punctuation">=</span>secret</span>
</code></pre>
<p>&#x67E5;&#x770B; <code>spring.couchbase.env.*</code> &#x83B7;&#x53D6;&#x66F4;&#x591A;&#x8BE6;&#x7EC6;&#x5185;&#x5BB9;&#x3002;</p>
<p><a id="boot-features-spring-data-couchbase-repositories"></a></p>
<h4 id="3182&#x3001;spring-data-couchbase-&#x8D44;&#x6E90;&#x5E93;">31.8.2&#x3001;Spring Data Couchbase &#x8D44;&#x6E90;&#x5E93;</h4>
<p>Spring Data &#x5305;&#x542B;&#x4E86; Couchbase &#x8D44;&#x6E90;&#x5E93;&#x652F;&#x6301;&#x3002;&#x6709;&#x5173; Spring Data Couchbase &#x7684;&#x5B8C;&#x6574;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605;&#x5176;<a href="https://docs.spring.io/spring-data/couchbase/docs/current/reference/html/" target="_blank">&#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x3002;</p>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x50CF;&#x4F7F;&#x7528;&#x5176;&#x4ED6; Spring Bean &#x4E00;&#x6837;&#x6CE8;&#x5165;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>CouchbaseTemplate</code> &#x5B9E;&#x4F8B;&#xFF0C;&#x524D;&#x63D0;&#x662F;&#x6709;&#x4E00;&#x4E2A;&#x9ED8;&#x8BA4;&#x7684;<code>CouchbaseConfigurer</code>&#xFF08;&#x5F53;&#x60A8;&#x542F;&#x7528; Couchbase &#x652F;&#x6301;&#x65F6;&#x4F1A;&#x53D1;&#x751F;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#xFF0C;&#x5982;&#x4E4B;&#x524D;&#x6240;&#x8FF0;&#xFF09;&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x6CE8;&#x5165;&#x4E00;&#x4E2A; Couchbase bean&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">CouchbaseTemplate</span> template<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">CouchbaseTemplate</span> template<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>template <span class="token operator">=</span> template<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x5728;&#x81EA;&#x5DF1;&#x7684;&#x914D;&#x7F6E;&#x4E2D;&#x5B9A;&#x4E49;&#x4EE5;&#x4E0B;&#x51E0;&#x4E2A; bean&#xFF0C;&#x4EE5;&#x8986;&#x76D6;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x63D0;&#x4F9B;&#x7684;&#x914D;&#x7F6E;&#xFF1A;</p>
<ul>
<li>&#x4E00;&#x4E2A;&#x540D;&#x4E3A; <code>couchbaseTemplate</code> &#x7684; <code>CouchbaseTemplate</code> @Bean</li>
<li>&#x4E00;&#x4E2A;&#x540D;&#x4E3A; <code>couchbaseIndexManager</code> &#x7684; <code>IndexManager</code> @Bean</li>
<li>&#x4E00;&#x4E2A;&#x540D;&#x4E3A; <code>couchbaseCustomConversions</code> &#x7684; <code>CustomConversions</code> @Bean</li>
</ul>
<p>&#x4E3A;&#x4E86;&#x907F;&#x514D;&#x5728;&#x81EA;&#x5DF1;&#x7684;&#x914D;&#x7F6E;&#x4E2D;&#x786C;&#x7F16;&#x7801;&#x8FD9;&#x4E9B;&#x540D;&#x79F0;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x91CD;&#x7528; Spring Data Couchbase &#x63D0;&#x4F9B;&#x7684; <code>BeanNames</code>&#xFF0C;&#x4F8B;&#x5982;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x81EA;&#x5B9A;&#x4E49;&#x8F6C;&#x6362;&#x5668;&#xFF0C;&#x5982;&#x4E0B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SomeConfiguration</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Bean</span><span class="token punctuation">(</span><span class="token class-name">BeanNames</span><span class="token punctuation">.</span>COUCHBASE_CUSTOM_CONVERSIONS<span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token class-name">CustomConversions</span> <span class="token function">myCustomConversions</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">CustomConversions</span><span class="token punctuation">(</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<p>&#x5982;&#x679C;&#x60A8;&#x60F3;&#x8981;&#x5B89;&#x5168;&#x7ED5;&#x5F00; Spring Data Couchbase &#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x8BF7;&#x63D0;&#x4F9B;&#x81EA;&#x5DF1;&#x7684; <code>org.springframework.data.couchbase.config.AbstractCouchbaseDataConfiguration</code> &#x5B9E;&#x73B0;&#x3002;</p>
<p><a id="boot-features-ldap"></a></p>
<h3 id="319&#x3001;ldap">31.9&#x3001;LDAP</h3>
<p><a href="https://en.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol" target="_blank">LDAP</a>&#xFF08;Lightweight Directory Access Protocol&#xFF0C;&#x8F7B;&#x91CF;&#x7EA7;&#x76EE;&#x5F55;&#x8BBF;&#x95EE;&#x534F;&#x8BAE;&#xFF09;&#x662F;&#x4E00;&#x4E2A;&#x5F00;&#x653E;&#x3001;&#x5382;&#x5546;&#x4E2D;&#x7ACB;&#x7684;&#x884C;&#x4E1A;&#x6807;&#x51C6;&#x5E94;&#x7528;&#x534F;&#x8BAE;&#xFF0C;&#x5176;&#x901A;&#x8FC7; IP &#x7F51;&#x7EDC;&#x8BBF;&#x95EE;&#x548C;&#x7EF4;&#x62A4;&#x5206;&#x5E03;&#x5F0F;&#x76EE;&#x5F55;&#x4FE1;&#x606F;&#x670D;&#x52A1;&#x3002;Spring Boot &#x4E3A;&#x517C;&#x5BB9; LDAP &#x670D;&#x52A1;&#x5668;&#x63D0;&#x4F9B;&#x4E86;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x4EE5;&#x53CA;&#x652F;&#x6301;&#x4ECE; <a href="https://www.ldap.com/unboundid-ldap-sdk-for-java" target="_blank">UnboundID</a> &#x5185;&#x5D4C;&#x5185;&#x5B58;&#x5F0F; LDAP &#x670D;&#x52A1;&#x5668;&#x3002;</p>
<p><a href="https://github.com/spring-projects/spring-data-ldap" target="_blank">Spring Data LDAP</a> &#x63D0;&#x4F9B;&#x4E86; LDAP &#x62BD;&#x8C61;&#x3002;&#x76F8;&#x5173;&#x4F9D;&#x8D56;&#x5305;&#x542B;&#x5728;&#x4E86; <code>spring-boot-starter-data-ldap</code> starter &#x4E2D;&#x3002;</p>
<p><a id="boot-features-ldap-connecting"></a></p>
<h4 id="3191&#x3001;&#x8FDE;&#x63A5;-ldap-&#x670D;&#x52A1;&#x5668;">31.9.1&#x3001;&#x8FDE;&#x63A5; LDAP &#x670D;&#x52A1;&#x5668;</h4>
<p>&#x8981;&#x8FDE;&#x63A5; LDAP &#x670D;&#x52A1;&#x5668;&#xFF0C;&#x8BF7;&#x786E;&#x4FDD;&#x60A8;&#x5DF2;&#x7ECF;&#x58F0;&#x660E;&#x4E86; <code>spring-boot-starter-data-ldap</code> starter &#x6216;&#x8005; <code>spring-ldap-core</code> &#x4F9D;&#x8D56;&#xFF0C;&#x7136;&#x540E;&#x5728; <code>application.properties</code> &#x58F0;&#x660E;&#x670D;&#x52A1;&#x5668;&#x7684; URL&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.ldap.urls</span><span class="token attr-value"><span class="token punctuation">=</span>ldap://myserver:1235</span>
<span class="token constant">spring.ldap.username</span><span class="token attr-value"><span class="token punctuation">=</span>admin</span>
<span class="token constant">spring.ldap.password</span><span class="token attr-value"><span class="token punctuation">=</span>secret</span>
</code></pre>
<p>&#x5982;&#x679C;&#x9700;&#x8981;&#x81EA;&#x5B9A;&#x4E49;&#x8FDE;&#x63A5;&#x8BBE;&#x7F6E;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.ldap.base</code> &#x548C; <code>spring.ldap.base-environment</code> &#x5C5E;&#x6027;&#x3002;</p>
<p><code>LdapContextSource</code> &#x5C06;&#x6839;&#x636E;&#x8FD9;&#x4E9B;&#x8BBE;&#x7F6E;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x81EA;&#x5B9A;&#x4E49;&#x5B83;&#xFF0C;&#x4F8B;&#x5982;&#x4F7F;&#x7528;&#x4E00;&#x4E2A; <code>PooledContextSource</code>&#xFF0C;&#x5219;&#x4ECD;&#x7136;&#x53EF;&#x4EE5;&#x6CE8;&#x5165;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>LdapContextSource</code>&#x3002;&#x786E;&#x4FDD;&#x5C06;&#x81EA;&#x5B9A;&#x4E49;&#x7684; <code>ContextSource</code> &#x6807;&#x8BB0;&#x4E3A; <code>@Primary</code>&#xFF0C;&#x4EE5;&#x4FBF;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>LdapTemplate</code> &#x80FD;&#x4F7F;&#x7528;&#x5B83;&#x3002;</p>
<p><a id="boot-features-ldap-spring-data-repositories"></a></p>
<h4 id="3192&#x3001;spring-data-ldap-&#x8D44;&#x6E90;&#x5E93;">31.9.2&#x3001;Spring Data LDAP &#x8D44;&#x6E90;&#x5E93;</h4>
<p>Spring Data &#x5305;&#x542B;&#x4E86; LDAP &#x8D44;&#x6E90;&#x5E93;&#x652F;&#x6301;&#x3002;&#x6709;&#x5173; Spring Data LDAP &#x7684;&#x5B8C;&#x6574;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605;&#x5176;<a href="https://docs.spring.io/spring-data/ldap/docs/1.0.x/reference/html/" target="_blank">&#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x3002;</p>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x50CF;&#x5176;&#x4ED6; Spring Bean &#x4E00;&#x6837;&#x6CE8;&#x5165;&#x4E00;&#x4E2A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>LdapTemplate</code> &#x5B9E;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">LdapTemplate</span> template<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">LdapTemplate</span> template<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>template <span class="token operator">=</span> template<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-ldap-embedded"></a></p>
<h4 id="3193&#x3001;&#x5185;&#x5D4C;&#x5185;&#x5B58;&#x5F0F;-ldap-&#x670D;&#x52A1;&#x5668;">31.9.3&#x3001;&#x5185;&#x5D4C;&#x5185;&#x5B58;&#x5F0F; LDAP &#x670D;&#x52A1;&#x5668;</h4>
<p>&#x4E3A;&#x4E86;&#x6D4B;&#x8BD5;&#x76EE;&#x7684;&#xFF0C;Spring Boot &#x652F;&#x6301;&#x4ECE; <a href="https://www.ldap.com/unboundid-ldap-sdk-for-java" target="_blank">UnboundID</a> &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A;&#x5185;&#x5B58;&#x5F0F; LDAP &#x670D;&#x52A1;&#x5668;&#x3002;&#x8981;&#x914D;&#x7F6E;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x8BF7;&#x6DFB;&#x52A0; <code>com.unboundid:unboundid-ldapsdk</code> &#x4F9D;&#x8D56;&#x5E76;&#x58F0;&#x660E;&#x4E00;&#x4E2A; <code>base-dn</code> &#x5C5E;&#x6027;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.ldap.embedded.base-dn</span><span class="token attr-value"><span class="token punctuation">=</span>dc=spring,dc=io</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>

&#x53EF;&#x4EE5;&#x5B9A;&#x4E49;&#x591A;&#x4E2A; `base-dn` &#x503C;&#xFF0C;&#x4F46;&#x662F;&#xFF0C;&#x7531;&#x4E8E;&#x540D;&#x79F0;&#x5305;&#x542B;&#x9017;&#x53F7;&#xFF0C;&#x5B58;&#x5728;&#x6B67;&#x4E49;&#xFF0C;&#x56E0;&#x6B64;&#x5FC5;&#x987B;&#x4F7F;&#x7528;&#x6B63;&#x786E;&#x7684;&#x7B26;&#x53F7;&#x6765;&#x5B9A;&#x4E49;&#x5B83;&#x4EEC;&#x3002;

&#x5728; yaml &#x6587;&#x4EF6;&#x4E2D;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; yaml &#x5217;&#x8868;&#x8868;&#x793A;&#x6CD5;&#xFF1A;

```yaml
spring.ldap.embedded.base-dn:
  - dc=spring,dc=io
  - dc=pivotal,dc=io
```

&#x5728;&#x5C5E;&#x6027;&#x6587;&#x4EF6;&#x4E2D;&#xFF0C;&#x5FC5;&#x987B;&#x4F7F;&#x7528;&#x7D22;&#x5F15;&#x65B9;&#x5F0F;&#xFF1A;

```ini
spring.ldap.embedded.base-dn[0]=dc=spring,dc=io
spring.ldap.embedded.base-dn[1]=dc=pivotal,dc=io
```

</blockquote>

<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x670D;&#x52A1;&#x5668;&#x5C06;&#x5728;&#x4E00;&#x4E2A;&#x968F;&#x673A;&#x7AEF;&#x53E3;&#x4E0A;&#x542F;&#x52A8;&#xFF0C;&#x5E76;&#x89E6;&#x53D1;&#x5E38;&#x89C4;&#x7684; LDAP &#x652F;&#x6301;&#xFF08;&#x4E0D;&#x9700;&#x8981;&#x6307;&#x5B9A; <code>spring.ldap.urls</code> &#x5C5E;&#x6027;&#xFF09;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x7684; classpath &#x4E0A;&#x5B58;&#x5728;&#x4E00;&#x4E2A; <code>schema.ldif</code> &#x6587;&#x4EF6;&#xFF0C;&#x5176;&#x5C06;&#x7528;&#x4E8E;&#x521D;&#x59CB;&#x5316;&#x670D;&#x52A1;&#x5668;&#x3002;&#x5982;&#x679C;&#x60A8;&#x60F3;&#x4ECE;&#x4E0D;&#x540C;&#x7684;&#x8D44;&#x6E90;&#x4E2D;&#x52A0;&#x8F7D;&#x811A;&#x672C;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.ldap.embedded.ldif</code> &#x5C5E;&#x6027;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5C06;&#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x6807;&#x51C6;&#x6A21;&#x5F0F;&#xFF08;schema&#xFF09;&#x6765;&#x6821;&#x9A8C; <code>LDIF</code> &#x6587;&#x4EF6;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.ldap.embedded.validation.enabled</code> &#x5C5E;&#x6027;&#x6765;&#x5173;&#x95ED;&#x6240;&#x6709;&#x6821;&#x9A8C;&#x3002;&#x5982;&#x679C;&#x60A8;&#x6709;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x5C5E;&#x6027;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.ldap.embedded.validation.schema</code> &#x6765;&#x5B9A;&#x4E49;&#x81EA;&#x5B9A;&#x4E49;&#x5C5E;&#x6027;&#x7C7B;&#x578B;&#x6216;&#x8005;&#x5BF9;&#x8C61;&#x7C7B;&#x3002;</p>
<p><a id="boot-features-influxdb"></a></p>
<h3 id="3110&#x3001;influxdb">31.10&#x3001;InfluxDB</h3>
<p><a href="https://www.influxdata.com/" target="_blank">InfluxDB</a> &#x662F;&#x4E00;&#x4E2A;&#x5F00;&#x6E90;&#x65F6;&#x5217;&#x6570;&#x636E;&#x5E93;&#xFF0C;&#x5176;&#x9488;&#x5BF9;&#x8FD0;&#x8425;&#x76D1;&#x63A7;&#x3001;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x6307;&#x6807;&#x3001;&#x7269;&#x8054;&#x7F51;&#x4F20;&#x611F;&#x5668;&#x6570;&#x636E;&#x548C;&#x5B9E;&#x65F6;&#x5206;&#x6790;&#x7B49;&#x9886;&#x57DF;&#x4E2D;&#x7684;&#x65F6;&#x95F4;&#x5E8F;&#x5217;&#x6570;&#x636E;&#x5728;&#x901F;&#x5EA6;&#x3001;&#x9AD8;&#x53EF;&#x7528;&#x5B58;&#x50A8;&#x548C;&#x68C0;&#x7D22;&#x65B9;&#x9762;&#x8FDB;&#x884C;&#x4E86;&#x4F18;&#x5316;&#x3002;</p>
<p><a id="boot-features-connecting-to-influxdb"></a></p>
<h4 id="31101&#x3001;&#x8FDE;&#x63A5;-influxdb">31.10.1&#x3001;&#x8FDE;&#x63A5; InfluxDB</h4>
<p>Spring Boot &#x81EA;&#x52A8;&#x914D;&#x7F6E; <code>InfluxDB</code> &#x5B9E;&#x4F8B;&#xFF0C;&#x524D;&#x63D0;&#x662F; <code>Influxdb-java</code> &#x5BA2;&#x6237;&#x7AEF;&#x5728; classpath &#x4E0A;&#x5E76;&#x4E14;&#x8BBE;&#x7F6E;&#x4E86;&#x6570;&#x636E;&#x5E93;&#x7684; URL&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.influx.url</span><span class="token attr-value"><span class="token punctuation">=</span>HTTP://172.0.0.1:8086</span>
</code></pre>
<p>&#x5982;&#x679C;&#x4E0E; InfluxDB &#x7684;&#x8FDE;&#x63A5;&#x9700;&#x8981;&#x7528;&#x6237;&#x548C;&#x5BC6;&#x7801;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x76F8;&#x5E94;&#x5730;&#x8BBE;&#x7F6E; <code>spring.influx.user</code> &#x548C; <code>spring.influx.password</code> &#x5C5E;&#x6027;&#x3002;</p>
<p>InfluxDB &#x4F9D;&#x8D56;&#x4E8E; OkHttp&#x3002;&#x5982;&#x679C;&#x4F60;&#x9700;&#x8981;&#x8C03;&#x6574; <code>InfluxDB</code> &#x5728;&#x5E95;&#x5C42;&#x4F7F;&#x7528;&#x7684; http &#x5BA2;&#x6237;&#x7AEF;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x6CE8;&#x518C;&#x4E00;&#x4E2A; <code>InfluxDbOkHttpClientBuilderProvider</code> bean&#x3002;</p>
<p><a id="boot-features-caching"></a></p>
<h2 id="32&#x3001;&#x7F13;&#x5B58;">32&#x3001;&#x7F13;&#x5B58;</h2>
<p>Spring Framework &#x652F;&#x6301;&#x4EE5;&#x900F;&#x660E;&#x7684;&#x65B9;&#x5F0F;&#x5411;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x6DFB;&#x52A0;&#x7F13;&#x5B58;&#x3002;&#x4ECE;&#x672C;&#x8D28;&#x4E0A;&#x8BB2;&#xFF0C;&#x5C06;&#x7F13;&#x5B58;&#x5E94;&#x7528;&#x4E8E;&#x65B9;&#x6CD5;&#x4E0A;&#xFF0C;&#x6839;&#x636E;&#x7F13;&#x5B58;&#x6570;&#x636E;&#x51CF;&#x5C11;&#x65B9;&#x6CD5;&#x7684;&#x6267;&#x884C;&#x6B21;&#x6570;&#x3002;&#x7F13;&#x5B58;&#x903B;&#x8F91;&#x662F;&#x900F;&#x660E;&#x7684;&#xFF0C;&#x4E0D;&#x4F1A;&#x5BF9;&#x8C03;&#x7528;&#x8005;&#x9020;&#x6210;&#x4EFB;&#x4F55;&#x5E72;&#x6270;&#x3002;&#x901A;&#x8FC7; <code>@EnableCaching</code> &#x6CE8;&#x89E3;&#x542F;&#x7528;&#x7F13;&#x5B58;&#x652F;&#x6301;&#xFF0C;Spring Boot &#x5C31;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7F13;&#x5B58;&#x8BBE;&#x7F6E;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x6709;&#x5173;&#x66F4;&#x591A;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x67E5;&#x770B; Spring Framework &#x53C2;&#x8003;&#x6587;&#x6863;&#x7684;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/integration.html#cache" target="_blank">&#x76F8;&#x5173;&#x90E8;&#x5206;</a>&#x3002;</p>
</blockquote>
<p>&#x7B80;&#x800C;&#x8A00;&#x4E4B;&#xFF0C;&#x4E3A;&#x670D;&#x52A1;&#x6DFB;&#x52A0;&#x7F13;&#x5B58;&#x7684;&#x64CD;&#x4F5C;&#x5C31;&#x50CF;&#x5728;&#x5176;&#x65B9;&#x6CD5;&#x4E2D;&#x6DFB;&#x52A0;&#x6CE8;&#x89E3;&#x4E00;&#x6837;&#x7B80;&#x5355;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>cache<span class="token punctuation">.</span>annotation</span><span class="token punctuation">.</span><span class="token class-name">Cacheable</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype</span><span class="token punctuation">.</span><span class="token class-name">Component</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MathService</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Cacheable</span><span class="token punctuation">(</span><span class="token string">&quot;piDecimals&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">int</span> <span class="token function">computePiDecimal</span><span class="token punctuation">(</span><span class="token keyword">int</span> i<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x6B64;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x5728;&#x4EE3;&#x4EF7;&#x53EF;&#x80FD;&#x9AD8;&#x6602;&#x7684;&#x64CD;&#x4F5C;&#x4E0A;&#x4F7F;&#x7528;&#x7F13;&#x5B58;&#x3002;&#x5728;&#x8C03;&#x7528; <code>computePiDecimal</code> &#x4E4B;&#x524D;&#xFF0C;&#x7F13;&#x5B58;&#x652F;&#x6301;&#x4F1A;&#x5728; <code>piDecimals</code> &#x7F13;&#x5B58;&#x4E2D;&#x67E5;&#x627E;&#x4E0E; <code>i</code> &#x53C2;&#x6570;&#x5339;&#x914D;&#x7684;&#x9879;&#x3002;&#x5982;&#x679C;&#x627E;&#x5230;&#xFF0C;&#x5219;&#x7F13;&#x5B58;&#x4E2D;&#x7684;&#x5185;&#x5BB9;&#x4F1A;&#x7ACB;&#x5373;&#x8FD4;&#x56DE;&#x7ED9;&#x8C03;&#x7528;&#x8005;&#xFF0C;&#x5E76;&#x4E0D;&#x4F1A;&#x8C03;&#x7528;&#x8BE5;&#x65B9;&#x6CD5;&#x3002;&#x5426;&#x5219;&#xFF0C;&#x5C06;&#x8C03;&#x7528;&#x8BE5;&#x65B9;&#x6CD5;&#xFF0C;&#x5E76;&#x5728;&#x8FD4;&#x56DE;&#x503C;&#x4E4B;&#x524D;&#x66F4;&#x65B0;&#x7F13;&#x5B58;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x6807;&#x51C6; JSR-107&#xFF08;JCache&#xFF09;&#x6CE8;&#x89E3;&#xFF08;&#x4F8B;&#x5982; <code>@CacheResult</code>&#xFF09;&#x3002;&#x4F46;&#x662F;&#xFF0C;&#x6211;&#x4EEC;&#x5F3A;&#x70C8;&#x5EFA;&#x8BAE;&#x60A8;<strong>&#x4E0D;&#x8981;</strong>&#x5C06; Spring Cache &#x548C; JCache &#x6CE8;&#x89E3;&#x6DF7;&#x5408;&#x4F7F;&#x7528;&#x3002;</p>
</blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x4E0D;&#x6DFB;&#x52A0;&#x4EFB;&#x4F55;&#x6307;&#x5B9A;&#x7684;&#x7F13;&#x5B58;&#x5E93;&#xFF0C;Spring Boot &#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A;&#x4F7F;&#x7528;&#x5E76;&#x53D1; map &#x7684; <a href="#boot-features-caching-provider-simple">simple provider</a>&#x3002;&#x5F53;&#x9700;&#x8981;&#x7F13;&#x5B58;&#x65F6;&#xFF08;&#x4F8B;&#x5982;&#x524D;&#x9762;&#x793A;&#x4F8B;&#x4E2D;&#x7684; <code>piDecimals</code>&#xFF09;&#xFF0C;&#x8BE5; simple provider &#x4F1A;&#x4E3A;&#x60A8;&#x521B;&#x5EFA;&#x7F13;&#x5B58;&#x3002;&#x4E0D;&#x63A8;&#x8350;&#x5C06; simple provider &#x7528;&#x4E8E;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#xFF0C;&#x4F46;&#x5B83;&#x975E;&#x5E38;&#x9002;&#x5408;&#x5165;&#x95E8;&#x5E76;&#x5E2E;&#x52A9;&#x60A8;&#x4E86;&#x89E3;&#x8FD9;&#x4E9B;&#x529F;&#x80FD;&#x3002;&#x5F53;&#x60A8;&#x51B3;&#x5B9A;&#x4F7F;&#x7528;&#x7F13;&#x5B58;&#x63D0;&#x4F9B;&#x8005;&#x65F6;&#xFF0C;&#x8BF7;&#x52A1;&#x5FC5;&#x9605;&#x8BFB;&#x5176;&#x6587;&#x6863;&#x4EE5;&#x4E86;&#x89E3;&#x5982;&#x4F55;&#x914D;&#x7F6E;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;&#x51E0;&#x4E4E;&#x6240;&#x6709;&#x63D0;&#x4F9B;&#x8005;&#x90FD;&#x8981;&#x6C42;&#x60A8;&#x663E;&#x5F0F;&#x914D;&#x7F6E;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x4F7F;&#x7528;&#x7684;&#x6BCF;&#x4E2A;&#x7F13;&#x5B58;&#x3002;&#x6709;&#x4E9B;&#x63D0;&#x4F9B;&#x4E86;&#x81EA;&#x5B9A;&#x4E49; <code>spring.cache.cache-names</code> &#x5C5E;&#x6027;&#x4EE5;&#x5B9A;&#x4E49;&#x9ED8;&#x8BA4;&#x7F13;&#x5B58;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x8FD8;&#x53EF;&#x4EE5;&#x900F;&#x660E;&#x5730;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/integration.html#cache-annotations-put" target="_blank">&#x66F4;&#x65B0;</a>&#x6216;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/integration.html#cache-annotations-evict" target="_blank">&#x56DE;&#x6536;</a>&#x7F13;&#x5B58;&#x4E2D;&#x7684;&#x6570;&#x636E;&#x3002;</p>
</blockquote>
<p><a id="boot-features-caching-provider"></a></p>
<h3 id="321&#x3001;&#x652F;&#x6301;&#x7684;&#x7F13;&#x5B58;&#x63D0;&#x4F9B;&#x8005;">32.1&#x3001;&#x652F;&#x6301;&#x7684;&#x7F13;&#x5B58;&#x63D0;&#x4F9B;&#x8005;</h3>
<p>&#x7F13;&#x5B58;&#x62BD;&#x8C61;&#x4E0D;&#x63D0;&#x4F9B;&#x5B58;&#x50A8;&#x5B9E;&#x73B0;&#xFF0C;&#x5176;&#x4F9D;&#x8D56;&#x4E8E; <code>org.springframework.cache.Cache</code> &#x548C; <code>org.springframework.cache.CacheManager</code> &#x63A5;&#x53E3;&#x5B9E;&#x73B0;&#x7684;&#x62BD;&#x8C61;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x672A;&#x5B9A;&#x4E49; <code>CacheManager</code> &#x7C7B;&#x578B;&#x7684; bean &#x6216;&#x540D;&#x4E3A; <code>cacheResolver</code> &#x7684; <code>CacheResolver</code>&#xFF08;&#x8BF7;&#x53C2;&#x9605; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/cache/annotation/CachingConfigurer.html" target="_blank"><code>CachingConfigurer</code></a>&#xFF09;&#xFF0C;&#x5219; Spring Boot &#x4F1A;&#x5C1D;&#x8BD5;&#x68C0;&#x6D4B;&#x4EE5;&#x4E0B;&#x63D0;&#x4F9B;&#x8005;&#xFF08;&#x6309;&#x5E8F;&#x53F7;&#x987A;&#x5E8F;&#xFF09;&#xFF1A;</p>
<ol>
<li><a href="#boot-features-caching-provider-generic">Generic</a></li>
<li><a href="#boot-features-caching-provider-jcache">JCache (JSR-107)</a>(EhCache 3&#x3001;Hazelcast&#x3001;Infinispan &#x6216;&#x5176;&#x4ED6;)</li>
<li><a href="#boot-features-caching-provider-ehcache2">EhCache 2.x</a></li>
<li><a href="#boot-features-caching-provider-hazelcast">Hazelcast</a></li>
<li><a href="#boot-features-caching-provider-infinispan">Infinispan</a></li>
<li><a href="#boot-features-caching-provider-couchbase">Couchbase</a></li>
<li><a href="#boot-features-caching-provider-redis">Redis</a>
8 <a href="#boot-features-caching-provider-caffeine">Caffeine</a></li>
<li><a href="#boot-features-caching-provider-simple">Simple</a></li>
</ol>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x4E5F;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>spring.cache.type</code> &#x5C5E;&#x6027;&#x6765;&#x5F3A;&#x5236;&#x6307;&#x5B9A;&#x7F13;&#x5B58;&#x63D0;&#x4F9B;&#x8005;&#x3002;&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x5728;&#x67D0;&#x4E9B;&#x73AF;&#x5883;&#xFF08;&#x6BD4;&#x5982;&#x6D4B;&#x8BD5;&#xFF09;&#x4E2D;<a href="#boot-features-caching-provider-none">&#x5B8C;&#x5168;&#x7981;&#x7528;&#x7F13;&#x5B58;</a>&#xFF0C;&#x8BF7;&#x4F7F;&#x7528;&#x6B64;&#x5C5E;&#x6027;&#x3002;</p>
</blockquote>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x4F7F;&#x7528; <code>spring-boot-starter-cache</code> starter &#x5FEB;&#x901F;&#x6DFB;&#x52A0;&#x57FA;&#x672C;&#x7684;&#x7F13;&#x5B58;&#x4F9D;&#x8D56;&#x3002;starter &#x5F15;&#x5165;&#x4E86; <code>spring-context-support</code>&#x3002;&#x5982;&#x679C;&#x624B;&#x52A8;&#x6DFB;&#x52A0;&#x4F9D;&#x8D56;&#xFF0C;&#x5219;&#x5FC5;&#x987B;&#x5305;&#x542B; <code>spring-context-support</code> &#x624D;&#x80FD;&#x4F7F;&#x7528; JCache&#x3001;EhCache 2.x &#x6216; Guava &#x652F;&#x6301;&#x3002;</p>
</blockquote>
<p>&#x5982;&#x679C;&#x901A;&#x8FC7; Spring Boot &#x81EA;&#x52A8;&#x914D;&#x7F6E; <code>CacheManager</code>&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x66B4;&#x9732;&#x4E00;&#x4E2A;&#x5B9E;&#x73B0;&#x4E86; <code>CacheManagerCustomizer</code> &#x63A5;&#x53E3;&#x7684; bean&#xFF0C;&#x5728;&#x5B8C;&#x5168;&#x521D;&#x59CB;&#x5316;&#x4E4B;&#x524D;&#x8FDB;&#x4E00;&#x6B65;&#x8C03;&#x6574;&#x5176;&#x914D;&#x7F6E;&#x3002;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x8BBE;&#x7F6E;&#x4E86;&#x4E00;&#x4E2A; flag&#xFF0C;&#x8868;&#x793A;&#x5E94;&#x5C06; null &#x503C;&#x4F20;&#x9012;&#x7ED9;&#x5E95;&#x5C42; map&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">CacheManagerCustomizer</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">ConcurrentMapCacheManager</span><span class="token punctuation">&gt;</span></span> <span class="token function">cacheManagerCustomizer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">CacheManagerCustomizer</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">ConcurrentMapCacheManager</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token annotation punctuation">@Override</span>
        <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">customize</span><span class="token punctuation">(</span><span class="token class-name">ConcurrentMapCacheManager</span> cacheManager<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            cacheManager<span class="token punctuation">.</span><span class="token function">setAllowNullValues</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5728;&#x524D;&#x9762;&#x793A;&#x4F8B;&#x4E2D;&#xFF0C;&#x9700;&#x8981;&#x4E00;&#x4E2A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>ConcurrentMapCacheManager</code>&#x3002;&#x5982;&#x679C;&#x4E0D;&#x662F;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#xFF08;&#x60A8;&#x63D0;&#x4F9B;&#x4E86;&#x81EA;&#x5DF1;&#x7684;&#x914D;&#x7F6E;&#x6216;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E86;&#x4E0D;&#x540C;&#x7684;&#x7F13;&#x5B58;&#x63D0;&#x4F9B;&#x8005;&#xFF09;&#xFF0C;&#x5219;&#x6839;&#x672C;&#x4E0D;&#x4F1A;&#x8C03;&#x7528; customizer&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x62E5;&#x6709;&#x591A;&#x4E2A; customizer&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@Order</code> &#x6216; <code>Ordered</code> &#x6765;&#x6392;&#x5E8F;&#x5B83;&#x4EEC;&#x3002;</p>
</blockquote>
<p><a id="boot-features-caching-provider-generic"></a></p>
<h4 id="3211&#x3001;generic">32.1.1&#x3001;Generic</h4>
<p>&#x5982;&#x679C;&#x4E0A;&#x4E0B;&#x6587;&#x5B9A;&#x4E49;&#x4E86;<strong>&#x81F3;&#x5C11;</strong>&#x4E00;&#x4E2A; <code>org.springframework.cache.Cache</code> bean&#xFF0C;&#x5219;&#x4F7F;&#x7528; Generic &#x7F13;&#x5B58;&#x3002;&#x5C06;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x5305;&#x88C5;&#x6240;&#x6709;&#x8BE5;&#x7C7B;&#x578B; bean &#x7684; <code>CacheManager</code>&#x3002;</p>
<p><a id="boot-features-caching-provider-jcache"></a></p>
<h4 id="3212&#x3001;jcache-jsr-107">32.1.2&#x3001;JCache (JSR-107)</h4>
<p><a href="https://jcp.org/en/jsr/detail?id=107" target="_blank">JCache</a> &#x901A;&#x8FC7; classpath &#x4E0A;&#x7684; <code>javax.cache.spi.CachingProvider</code>&#xFF08;&#x5373; classpath &#x4E0A;&#x5B58;&#x5728;&#x7B26;&#x5408; JSR-107 &#x7684;&#x7F13;&#x5B58;&#x5E93;&#xFF09;&#x6765;&#x5F15;&#x5BFC;&#xFF0C;<code>jCacheCacheManager</code> &#x7531; <code>spring-boot-starter-cache</code> starter &#x63D0;&#x4F9B;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x5404;&#x79CD;&#x517C;&#x5BB9;&#x5E93;&#xFF0C;Spring Boot &#x4E3A; Ehcache 3&#x3001;Hazelcast &#x548C; Infinispan &#x63D0;&#x4F9B;&#x4F9D;&#x8D56;&#x7BA1;&#x7406;&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x6DFB;&#x52A0;&#x4EFB;&#x4F55;&#x5176;&#x4ED6;&#x517C;&#x5BB9;&#x5E93;&#x3002;</p>
<p>&#x53EF;&#x80FD;&#x5B58;&#x5728;&#x591A;&#x4E2A;&#x63D0;&#x4F9B;&#x8005;&#xFF0C;&#x5728;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#x5FC5;&#x987B;&#x660E;&#x786E;&#x6307;&#x5B9A;&#x63D0;&#x4F9B;&#x8005;&#x3002;&#x5373;&#x4F7F; JSR-107 &#x6807;&#x51C6;&#x6CA1;&#x6709;&#x5F3A;&#x5236;&#x89C4;&#x5B9A;&#x4E00;&#x4E2A;&#x5B9A;&#x4E49;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4F4D;&#x7F6E;&#x7684;&#x6807;&#x51C6;&#x5316;&#x65B9;&#x6CD5;&#xFF0C;Spring Boot &#x4E5F;&#x4F1A;&#x5C3D;&#x5176;&#x6240;&#x80FD;&#x8BBE;&#x7F6E;&#x4E00;&#x4E2A;&#x5305;&#x542B;&#x5B9E;&#x73B0;&#x7EC6;&#x8282;&#x7684;&#x7F13;&#x5B58;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token comment"># &#x5B58;&#x5728;&#x591A;&#x4E2A; provider &#x624D;&#x9700;&#x8981;&#x8FD9;&#x6837;&#x505A;</span>
<span class="token constant">spring.cache.jcache.provider</span><span class="token attr-value"><span class="token punctuation">=</span>com.acme.MyCachingProvider</span>
<span class="token constant">spring.cache.jcache.config</span><span class="token attr-value"><span class="token punctuation">=</span>classpath:acme.xml</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5F53;&#x7F13;&#x5B58;&#x5E93;&#x540C;&#x65F6;&#x63D0;&#x4F9B;&#x539F;&#x751F;&#x5B9E;&#x73B0;&#x548C; JSR-107 &#x652F;&#x6301;&#x65F6;&#xFF0C;Spring Boot &#x66F4;&#x503E;&#x5411; JSR-107 &#x652F;&#x6301;&#xFF0C;&#x56E0;&#x6B64;&#x5F53;&#x60A8;&#x5207;&#x6362;&#x5230;&#x4E0D;&#x540C;&#x7684; JSR-107 &#x5B9E;&#x73B0;&#x65F6;&#xFF0C;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x76F8;&#x540C;&#x7684;&#x529F;&#x80FD;&#x3002;</p>
</blockquote>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>Spring Boot &#x5BF9; <a href="#boot-features-hazelcast">Hazelcast</a> &#x7684;&#x652F;&#x6301;&#x4E00;&#x822C;&#x3002;&#x5982;&#x679C;&#x6709;&#x4E00;&#x4E2A; <code>HazelcastInstance</code> &#x53EF;&#x7528;&#xFF0C;&#x5B83;&#x4E5F;&#x4F1A;&#x81EA;&#x52A8;&#x4E3A; <code>CacheManager</code> &#x590D;&#x7528;&#xFF0C;&#x9664;&#x975E;&#x6307;&#x5B9A;&#x4E86; <code>spring.cache.jcache.config</code> &#x5C5E;&#x6027;&#x3002;</p>
</blockquote>
<p>&#x6709;&#x4E24;&#x79CD;&#x65B9;&#x6CD5;&#x53EF;&#x4EE5;&#x81EA;&#x5B9A;&#x4E49;&#x5E95;&#x5C42;&#x7684; <code>javax.cache.cacheManager</code>&#xFF1A;</p>
<ul>
<li>&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>spring.cache.cache-names</code> &#x5C5E;&#x6027;&#x5728;&#x542F;&#x52A8;&#x65F6;&#x521B;&#x5EFA;&#x7F13;&#x5B58;&#x3002;&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86;&#x81EA;&#x5B9A;&#x4E49; <code>javax.cache.configuration.Configuration</code> bean&#xFF0C;&#x5219;&#x4F1A;&#x4F7F;&#x7528;&#x5B83;&#x6765;&#x81EA;&#x5B9A;&#x4E49;&#x3002;</li>
<li>&#x4F7F;&#x7528; <code>CacheManager</code> &#x7684;&#x5F15;&#x7528;&#x8C03;&#x7528; <code>org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer</code> bean &#x4EE5;&#x8FDB;&#x884C;&#x5B8C;&#x5168;&#x81EA;&#x5B9A;&#x4E49;&#x3002;</li>
</ul>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86;&#x4E00;&#x4E2A;&#x6807;&#x51C6;&#x7684; <code>javax.cache.CacheManager</code> bean&#xFF0C;&#x5B83;&#x5C06;&#x81EA;&#x52A8;&#x5305;&#x88C5;&#x8FDB;&#x4E00;&#x4E2A;&#x62BD;&#x8C61;&#x6240;&#x9700;&#x7684; <code>org.springframework.cache.CacheManager</code> &#x5B9E;&#x73B0;&#x4E2D;&#xFF0C;&#x800C;&#x4E0D;&#x4F1A;&#x5E94;&#x7528;&#x81EA;&#x5B9A;&#x4E49;&#x914D;&#x7F6E;&#x3002;</p>
</blockquote>
<p><a id="boot-features-caching-provider-ehcache2"></a></p>
<h4 id="3213&#x3001;ehcache-2x">32.1.3&#x3001;EhCache 2.x</h4>
<p>&#x5982;&#x679C;&#x53EF;&#x4EE5;&#x5728; classpath &#x7684;&#x6839;&#x76EE;&#x5F55;&#x4E2D;&#x627E;&#x5230;&#x540D;&#x4E3A; <code>ehcache.xml</code> &#x7684;&#x6587;&#x4EF6;&#xFF0C;&#x5219;&#x4F7F;&#x7528; EhCache 2.x&#x3002;&#x5982;&#x679C;&#x627E;&#x5230; EhCache 2.x&#xFF0C;&#x5219;&#x4F7F;&#x7528; <code>spring-boot-starter-cache</code> starter &#x63D0;&#x4F9B;&#x7684; <code>EhCacheCacheManager</code> &#x6765;&#x542F;&#x52A8;&#x7F13;&#x5B58;&#x7BA1;&#x7406;&#x5668;&#x3002;&#x8FD8;&#x53EF;&#x4EE5;&#x63D0;&#x4F9B;&#x5176;&#x4ED6;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.cache.ehcache.config</span><span class="token attr-value"><span class="token punctuation">=</span>classpath:config/another-config.xml</span>
</code></pre>
<p><a id="boot-features-caching-provider-hazelcast"></a></p>
<h4 id="3214&#x3001;hazelcast">32.1.4&#x3001;Hazelcast</h4>
<p>Spring Boot &#x5BF9; <a href="#boot-features-hazelcast">Hazelcast</a> &#x7684;&#x652F;&#x6301;&#x4E00;&#x822C;&#x3002;&#x5982;&#x679C;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E86;&#x4E00;&#x4E2A; <code>HazelcastInstance</code>&#xFF0C;&#x5B83;&#x5C06;&#x81EA;&#x52A8;&#x5305;&#x88C5;&#x8FDB; <code>CacheManager</code> &#x4E2D;&#x3002;</p>
<p><a id="boot-features-caching-provider-infinispan"></a></p>
<h4 id="3215&#x3001;infinispan">32.1.5&#x3001;Infinispan</h4>
<p><a href="http://infinispan.org/" target="_blank">Infinispan</a> &#x6CA1;&#x6709;&#x9ED8;&#x8BA4;&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x4F4D;&#x7F6E;&#xFF0C;&#x56E0;&#x6B64;&#x5FC5;&#x987B;&#x660E;&#x786E;&#x6307;&#x5B9A;&#x3002;&#x5426;&#x5219;&#x5C06;&#x4F7F;&#x7528;&#x9ED8;&#x8BA4;&#x914D;&#x7F6E;&#x5F15;&#x5BFC;&#x3002;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.cache.infinispan.config</span><span class="token attr-value"><span class="token punctuation">=</span>infinispan.xml</span>
</code></pre>
<p>&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>spring.cache.cache-names</code> &#x5C5E;&#x6027;&#x5728;&#x542F;&#x52A8;&#x65F6;&#x521B;&#x5EFA;&#x7F13;&#x5B58;&#x3002;&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86;&#x81EA;&#x5B9A;&#x4E49; <code>ConfigurationBuilder</code> bean&#xFF0C;&#x5219;&#x5B83;&#x5C06;&#x7528;&#x4E8E;&#x81EA;&#x5B9A;&#x4E49;&#x7F13;&#x5B58;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>Infinispan &#x5728; Spring Boot &#x4E2D;&#x7684;&#x652F;&#x6301;&#x4EC5;&#x9650;&#x4E8E;&#x5185;&#x5D4C;&#x6A21;&#x5F0F;&#xFF0C;&#x975E;&#x5E38;&#x7B80;&#x5355;&#x3002;&#x5982;&#x679C;&#x4F60;&#x60F3;&#x8981;&#x66F4;&#x591A;&#x9009;&#x9879;&#xFF0C;&#x4F60;&#x5E94;&#x8BE5;&#x4F7F;&#x7528;&#x5B98;&#x65B9;&#x7684; Infinispan Spring Boot starter&#x3002;&#x6709;&#x5173;&#x66F4;&#x591A;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/infinispan/infinispan-spring-boot" target="_blank">Infinispan &#x6587;&#x6863;</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-caching-provider-couchbase"></a></p>
<h4 id="3216&#x3001;couchbase">32.1.6&#x3001;Couchbase</h4>
<p>&#x5982;&#x679C; <a href="https://www.couchbase.com/" target="_blank">Couchbase</a> Java &#x5BA2;&#x6237;&#x7AEF;&#x548C; <code>couchbase-spring-cache</code> &#x5B9E;&#x73B0;&#x53EF;&#x7528;&#x4E14;&#x5DF2;&#x7ECF;<a href="#boot-features-couchbase">&#x914D;&#x7F6E;</a>&#x4E86; Couchbase&#xFF0C;&#x5219;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A; <code>CouchbaseCacheManager</code>&#x3002;&#x4E5F;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>spring.cache.cache-names</code> &#x5C5E;&#x6027;&#x5728;&#x542F;&#x52A8;&#x65F6;&#x521B;&#x5EFA;&#x5176;&#x4ED6;&#x7F13;&#x5B58;&#x3002;&#x8FD9;&#x4E9B;&#x7F13;&#x5B58;&#x5728;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; Bucket &#x4E0A;&#x64CD;&#x4F5C;&#x3002;&#x60A8;<strong>&#x8FD8;</strong>&#x53EF;&#x4EE5;&#x4F7F;&#x7528; customizer &#x5728;&#x5176;&#x4ED6; <code>Bucket</code> &#x4E0A;&#x521B;&#x5EFA;&#x7F13;&#x5B58;&#x3002;&#x5047;&#x8BBE;&#x60A8;&#x9700;&#x8981;&#x5728; <strong>main</strong> <code>Bucket</code> &#x4E0A;&#x6709;&#x4E24;&#x4E2A;&#x7F13;&#x5B58;&#xFF08;<code>cache1</code> &#x548C; <code>cache2</code>&#xFF09;&#xFF0C;&#x5E76;&#x4E14; <strong>another</strong> <code>Bucket</code> &#x6709;&#x4E00;&#x4E2A;&#x8FC7;&#x671F;&#x65F6;&#x95F4;&#x4E3A; 2 &#x79D2;&#x7684;&#x7F13;&#x5B58;&#xFF08;<code>cache3</code>&#xFF09;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x914D;&#x7F6E;&#x521B;&#x5EFA;&#x8FD9;&#x4E24;&#x4E2A;&#x7F13;&#x5B58;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.cache.cache-names</span><span class="token attr-value"><span class="token punctuation">=</span>cache1,cache2</span>
</code></pre>
<p>&#x7136;&#x540E;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A; <code>@Configuration</code> &#x7C7B;&#x6765;&#x914D;&#x7F6E;&#x5176;&#x4ED6; <code>Bucket</code> &#x548C; <code>cache3</code> &#x7F13;&#x5B58;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">CouchbaseCacheConfiguration</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">Cluster</span> cluster<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">CouchbaseCacheConfiguration</span><span class="token punctuation">(</span><span class="token class-name">Cluster</span> cluster<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>cluster <span class="token operator">=</span> cluster<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">Bucket</span> <span class="token function">anotherBucket</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>cluster<span class="token punctuation">.</span><span class="token function">openBucket</span><span class="token punctuation">(</span><span class="token string">&quot;another&quot;</span><span class="token punctuation">,</span> <span class="token string">&quot;secret&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">CacheManagerCustomizer</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">CouchbaseCacheManager</span><span class="token punctuation">&gt;</span></span> <span class="token function">cacheManagerCustomizer</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> c <span class="token operator">-&gt;</span> <span class="token punctuation">{</span>
            c<span class="token punctuation">.</span><span class="token function">prepareCache</span><span class="token punctuation">(</span><span class="token string">&quot;cache3&quot;</span><span class="token punctuation">,</span> <span class="token class-name">CacheBuilder</span><span class="token punctuation">.</span><span class="token function">newInstance</span><span class="token punctuation">(</span><span class="token function">anotherBucket</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
                    <span class="token punctuation">.</span><span class="token function">withExpiration</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x6B64;&#x793A;&#x4F8B;&#x914D;&#x7F6E;&#x590D;&#x7528;&#x4E86;&#x901A;&#x8FC7;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x521B;&#x5EFA;&#x7684; <code>Cluster</code>&#x3002;</p>
<p><a id="boot-features-caching-provider-redis"></a></p>
<h4 id="3217&#x3001;redis">32.1.7&#x3001;Redis</h4>
<p>&#x5982;&#x679C; <a href="http://redis.io/" target="_blank">Redis</a> &#x53EF;&#x7528;&#x5E76;&#x5DF2;&#x7ECF;&#x914D;&#x7F6E;&#xFF0C;&#x5219;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A; <code>RedisCacheManager</code>&#x3002;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>spring.cache.cache-names</code> &#x5C5E;&#x6027;&#x53EF;&#x4EE5;&#x5728;&#x542F;&#x52A8;&#x65F6;&#x521B;&#x5EFA;&#x5176;&#x4ED6;&#x7F13;&#x5B58;&#xFF0C;&#x5E76;&#x4E14;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.cache.redis.*</code> &#x5C5E;&#x6027;&#x914D;&#x7F6E;&#x7F13;&#x5B58;&#x9ED8;&#x8BA4;&#x503C;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x4EE5;&#x4E0B;&#x914D;&#x7F6E;&#x521B;&#x5EFA; <code>cache1</code> &#x548C; <code>cache2</code> &#x7F13;&#x5B58;&#xFF0C;&#x4ED6;&#x4EEC;&#x7684;<strong>&#x6709;&#x6548;&#x65F6;&#x95F4;</strong>&#x4E3A; 10 &#x5206;&#x949F;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.cache.cache-names</span><span class="token attr-value"><span class="token punctuation">=</span>cache1,cache2</span>
<span class="token constant">spring.cache.redis.time-to-live</span><span class="token attr-value"><span class="token punctuation">=</span>600000</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x4F1A;&#x6DFB;&#x52A0;&#x4E00;&#x4E2A; key &#x524D;&#x7F00;&#xFF0C;&#x8FD9;&#x6837;&#x505A;&#x662F;&#x56E0;&#x4E3A;&#x5982;&#x679C;&#x4E24;&#x4E2A;&#x5355;&#x72EC;&#x7684;&#x7F13;&#x5B58;&#x4F7F;&#x7528;&#x4E86;&#x76F8;&#x540C;&#x7684;&#x952E;&#xFF0C;Redis &#x4E0D;&#x652F;&#x6301;&#x91CD;&#x53E0; key&#xFF0C;&#x800C;&#x7F13;&#x5B58;&#x4E5F;&#x4E0D;&#x80FD;&#x8FD4;&#x56DE;&#x65E0;&#x6548;&#x503C;&#x3002;&#x5982;&#x679C;&#x60A8;&#x521B;&#x5EFA;&#x81EA;&#x5DF1;&#x7684; <code>RedisCacheManager</code>&#xFF0C;&#x6211;&#x4EEC;&#x5F3A;&#x70C8;&#x5EFA;&#x8BAE;&#x60A8;&#x542F;&#x7528;&#x6B64;&#x8BBE;&#x7F6E;&#x3002;</p>
</blockquote>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6DFB;&#x52A0;&#x81EA;&#x5DF1;&#x7684; <code>RedisCacheConfiguration</code> <code>@Bean</code> &#x6765;&#x5B8C;&#x5168;&#x63A7;&#x5236;&#x914D;&#x7F6E;&#x3002;&#x5982;&#x679C;&#x60A8;&#x60F3;&#x81EA;&#x5B9A;&#x4E49;&#x5E8F;&#x5217;&#x5316;&#x7B56;&#x7565;&#xFF0C;&#x8FD9;&#x79CD;&#x65B9;&#x5F0F;&#x53EF;&#x80FD;&#x5F88;&#x6709;&#x7528;&#x3002;</p>
</blockquote>
<p><a id="boot-features-caching-provider-caffeine"></a></p>
<h4 id="3218&#x3001;caffeine">32.1.8&#x3001;Caffeine</h4>
<p><a href="https://github.com/ben-manes/caffeine" target="_blank">Caffeine</a> &#x662F;&#x4E00;&#x4E2A;&#x4F7F;&#x7528;&#x4E86; Java 8 &#x91CD;&#x5199; Guava &#x7F13;&#x5B58;&#xFF0C;&#x7528;&#x4E8E;&#x53D6;&#x4EE3; Guava &#x652F;&#x6301;&#x7684;&#x7F13;&#x5B58;&#x5E93;&#x3002;&#x5982;&#x679C; Caffeine &#x5B58;&#x5728;&#xFF0C;&#x5219;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A; <code>CaffeineCacheManager</code>&#xFF08;&#x7531; <code>spring-boot-starter-cache</code> starter &#x63D0;&#x4F9B;&#xFF09;&#x3002;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>spring.cache.cache-names</code> &#x5C5E;&#x6027;&#x5728;&#x542F;&#x52A8;&#x65F6;&#x521B;&#x5EFA;&#x7F13;&#x5B58;&#xFF0C;&#x5E76;&#x4E14;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4EE5;&#x4E0B;&#x65B9;&#x5F0F;&#x4E4B;&#x4E00;&#xFF08;&#x6309;&#x5E8F;&#x53F7;&#x987A;&#x5E8F;&#xFF09;&#x81EA;&#x5B9A;&#x4E49;&#x7F13;&#x5B58;&#xFF1A;</p>
<ol>
<li>&#x4E00;&#x4E2A;&#x7531; <code>spring.cache.caffeine.spec</code> &#x5B9A;&#x4E49;&#x7684;&#x7F13;&#x5B58;&#x89C4;&#x8303;</li>
<li>&#x4E00;&#x4E2A;&#x5DF2;&#x5B9A;&#x4E49;&#x7684; <code>com.github.benmanes.caffeine.cache.CaffeineSpec</code> bean</li>
<li>&#x4E00;&#x4E2A;&#x5DF2;&#x5B9A;&#x4E49;&#x7684; <code>com.github.benmanes.caffeine.cache.Caffeine</code> bean</li>
</ol>
<p>&#x4F8B;&#x5982;&#xFF0C;&#x4EE5;&#x4E0B;&#x914D;&#x7F6E;&#x521B;&#x5EFA; <code>cache1</code> &#x548C; <code>cache2</code> &#x7F13;&#x5B58;&#xFF0C;&#x6700;&#x5927;&#x5927;&#x5C0F;&#x4E3A; 500&#xFF0C;<strong>&#x6709;&#x6548;&#x65F6;&#x95F4;</strong> &#x4E3A; 10 &#x5206;&#x949F;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.cache.cache-names</span><span class="token attr-value"><span class="token punctuation">=</span>cache1,cache2</span>
<span class="token constant">spring.cache.caffeine.spec</span><span class="token attr-value"><span class="token punctuation">=</span>maximumSize=500,expireAfterAccess=600s</span>
</code></pre>
<p>&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86; <code>com.github.benmanes.caffeine.cache.CacheLoader</code> bean&#xFF0C;&#x5B83;&#x5C06;&#x81EA;&#x52A8;&#x4E0E; <code>CaffeineCacheManager</code> &#x5173;&#x8054;&#x3002;&#x7531;&#x4E8E; <code>CacheLoader</code> &#x5C06;&#x4E0E;&#x7F13;&#x5B58;&#x7BA1;&#x7406;&#x5668;&#x7BA1;&#x7406;&#x7684;<strong>&#x6240;&#x6709;</strong>&#x7F13;&#x5B58;&#x76F8;&#x5173;&#x8054;&#xFF0C;&#x56E0;&#x6B64;&#x5FC5;&#x987B;&#x5C06;&#x5176;&#x5B9A;&#x4E49;&#x4E3A; <code>CacheLoader<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>Object,</span> <span class="token attr-name">Object</span><span class="token punctuation">&gt;</span></span></code>&#x3002;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4F1A;&#x5FFD;&#x7565;&#x6240;&#x6709;&#x5176;&#x4ED6;&#x6CDB;&#x578B;&#x7C7B;&#x578B;&#x3002;</p>
<p><a id="boot-features-caching-provider-simple"></a></p>
<h4 id="3219&#x3001;simple">32.1.9&#x3001;Simple</h4>
<p>&#x5982;&#x679C;&#x627E;&#x4E0D;&#x5230;&#x5176;&#x4ED6;&#x63D0;&#x4F9B;&#x8005;&#xFF0C;&#x5219;&#x914D;&#x7F6E;&#x4F7F;&#x7528;&#x4E00;&#x4E2A; <code>ConcurrentHashMap</code> &#x4F5C;&#x4E3A;&#x7F13;&#x5B58;&#x5B58;&#x50A8;&#x7684;&#x7B80;&#x5355;&#x5B9E;&#x73B0;&#x3002;&#x5982;&#x679C;&#x60A8;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x6CA1;&#x6709;&#x7F13;&#x5B58;&#x5E93;&#xFF0C;&#x5219;&#x8BE5;&#x9879;&#x4E3A;&#x9ED8;&#x8BA4;&#x503C;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x4F1A;&#x6839;&#x636E;&#x9700;&#x8981;&#x521B;&#x5EFA;&#x7F13;&#x5B58;&#xFF0C;&#x4F46;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>cache-names</code> &#x5C5E;&#x6027;&#x6765;&#x9650;&#x5236;&#x53EF;&#x7528;&#x7F13;&#x5B58;&#x7684;&#x5217;&#x8868;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5982;&#x679C;&#x53EA;&#x9700;&#x8981; <code>cache1</code> &#x548C; <code>cache2</code> &#x7F13;&#x5B58;&#xFF0C;&#x8BF7;&#x6309;&#x5982;&#x4E0B;&#x8BBE;&#x7F6E; <code>cache-names</code> &#x5C5E;&#x6027;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.cache.cache-names</span><span class="token attr-value"><span class="token punctuation">=</span>cache1,cache2</span>
</code></pre>
<p>&#x5982;&#x679C;&#x8FD9;&#x6837;&#x505A;&#x4E86;&#xFF0C;&#x5E76;&#x4E14;&#x60A8;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4F7F;&#x7528;&#x4E86;&#x672A;&#x5217;&#x51FA;&#x7684;&#x7F13;&#x5B58;&#xFF0C;&#x5219;&#x8FD0;&#x884C;&#x65F6;&#x5728;&#x5B83;&#x9700;&#x8981;&#x7F13;&#x5B58;&#x65F6;&#x4F1A;&#x89E6;&#x53D1;&#x5931;&#x8D25;&#xFF0C;&#x4F46;&#x5728;&#x542F;&#x52A8;&#x65F6;&#x5219;&#x4E0D;&#x4F1A;&#x3002;&#x8FD9;&#x7C7B;&#x4F3C;&#x4E8E;<strong>&#x771F;&#x5B9E;</strong>&#x7F13;&#x5B58;&#x63D0;&#x4F9B;&#x8005;&#x5728;&#x4F7F;&#x7528;&#x672A;&#x58F0;&#x660E;&#x7684;&#x7F13;&#x5B58;&#x65F6;&#x89E6;&#x53D1;&#x7684;&#x884C;&#x4E3A;&#x65B9;&#x5F0F;&#x3002;</p>
<p><a id="boot-features-caching-provider-none"></a></p>
<h4 id="32110&#x3001;none">32.1.10&#x3001;None</h4>
<p>&#x5F53;&#x914D;&#x7F6E;&#x4E2D;&#x5B58;&#x5728; <code>@EnableCaching</code> &#x65F6;&#xFF0C;&#x4E5F;&#x9700;&#x8981;&#x5408;&#x9002;&#x7684;&#x7F13;&#x5B58;&#x914D;&#x7F6E;&#x3002;&#x5982;&#x679C;&#x9700;&#x8981;&#x5728;&#x67D0;&#x4E9B;&#x73AF;&#x5883;&#x4E2D;&#x5B8C;&#x5168;&#x7981;&#x7528;&#x7F13;&#x5B58;&#xFF0C;&#x8BF7;&#x5C06;&#x7F13;&#x5B58;&#x7C7B;&#x578B;&#x5F3A;&#x5236;&#x8BBE;&#x7F6E;&#x4E3A; <code>none</code> &#x4EE5;&#x4F7F;&#x7528; no-op &#x5B9E;&#x73B0;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.cache.type</span><span class="token attr-value"><span class="token punctuation">=</span>none</span>
</code></pre>
<p><a id="boot-features-messaging"></a></p>
<h2 id="33&#x3001;&#x6D88;&#x606F;&#x4F20;&#x9012;">33&#x3001;&#x6D88;&#x606F;&#x4F20;&#x9012;</h2>
<p>Spring Framework &#x4E3A;&#x6D88;&#x606F;&#x4F20;&#x9012;&#x7CFB;&#x7EDF;&#x96C6;&#x6210;&#x63D0;&#x4F9B;&#x4E86;&#x5E7F;&#x6CDB;&#x7684;&#x652F;&#x6301;&#xFF0C;&#x4ECE;&#x4F7F;&#x7528; <code>JmsTemplate</code> &#x7B80;&#x5316; JMS API &#x7684;&#x4F7F;&#x7528;&#x5230;&#x5F02;&#x6B65;&#x63A5;&#x6536;&#x6D88;&#x606F;&#x7684;&#x5B8C;&#x6574;&#x57FA;&#x7840;&#x8BBE;&#x65BD;&#x3002;Spring AMQP &#x4E3A;&#x9AD8;&#x7EA7;&#x6D88;&#x606F;&#x961F;&#x5217;&#x534F;&#x8BAE;&#xFF08;Advanced Message Queuing Protocol&#xFF0C;AMQP&#xFF09;&#x63D0;&#x4F9B;&#x4E86;&#x7C7B;&#x4F3C;&#x7684;&#x529F;&#x80FD;&#x96C6;&#x5408;&#x3002;Spring Boot &#x8FD8;&#x4E3A; <code>RabbitTemplate</code> &#x548C; RabbitMQ &#x63D0;&#x4F9B;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x9009;&#x9879;&#x3002;Spring WebSocket &#x672C;&#x8EAB;&#x5305;&#x542B;&#x4E86;&#x5BF9; STOMP &#x6D88;&#x606F;&#x4F20;&#x9012;&#x7684;&#x652F;&#x6301;&#xFF0C;Spring Boot &#x901A;&#x8FC7; starter &#x548C;&#x5C11;&#x91CF;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x5373;&#x53EF;&#x652F;&#x6301;&#x5B83;&#x3002;Spring Boot &#x540C;&#x6837;&#x652F;&#x6301; Apache Kafka&#x3002;</p>
<p><a id="boot-features-jms"></a></p>
<h3 id="331&#x3001;jms">33.1&#x3001;JMS</h3>
<p><code>javax.jms.ConnectionFactory</code> &#x63A5;&#x53E3;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x79CD;&#x521B;&#x5EFA; <code>javax.jms.Connection</code> &#x7684;&#x6807;&#x51C6;&#x65B9;&#x6CD5;&#xFF0C;&#x53EF;&#x4E0E; JMS broker&#xFF08;&#x4EE3;&#x7406;&#xFF09;&#x8FDB;&#x884C;&#x4EA4;&#x4E92;&#x3002;&#x867D;&#x7136; Spring &#x9700;&#x8981;&#x4E00;&#x4E2A; <code>ConnectionFactory</code> &#x6765;&#x4E0E; JMS &#x4E00;&#x540C;&#x5DE5;&#x4F5C;&#xFF0C;&#x4F46;&#x662F;&#x60A8;&#x901A;&#x5E38;&#x4E0D;&#x9700;&#x8981;&#x81EA;&#x5DF1;&#x76F4;&#x63A5;&#x4F7F;&#x7528;&#x5B83;&#xFF0C;&#x800C;&#x662F;&#x53EF;&#x4EE5;&#x4F9D;&#x8D56;&#x66F4;&#x9AD8;&#x7EA7;&#x522B;&#x7684;&#x6D88;&#x606F;&#x4F20;&#x9012;&#x62BD;&#x8C61;&#x3002;&#xFF08;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; Spring Framework &#x53C2;&#x8003;&#x6587;&#x6863;&#x7684;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/integration.html#jms" target="_blank">&#x76F8;&#x5173;&#x90E8;&#x5206;</a>&#x3002;&#xFF09;Spring Boot &#x8FD8;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x53D1;&#x9001;&#x548C;&#x63A5;&#x6536;&#x6D88;&#x606F;&#x6240;&#x9700;&#x7684;&#x57FA;&#x7840;&#x8BBE;&#x65BD;&#x3002;</p>
<p><a id="boot-features-activemq"></a></p>
<h4 id="3311&#x3001;activemq-&#x652F;&#x6301;">33.1.1&#x3001;ActiveMQ &#x652F;&#x6301;</h4>
<p>&#x5F53; <a href="http://activemq.apache.org/" target="_blank">ActiveMQ</a> &#x5728; classpath &#x4E0A;&#x53EF;&#x7528;&#x65F6;&#xFF0C;Spring Boot &#x4E5F;&#x53EF;&#x4EE5;&#x914D;&#x7F6E;&#x4E00;&#x4E2A; <code>ConnectionFactory</code>&#x3002;&#x5982;&#x679C; broker &#x5B58;&#x5728;&#xFF0C;&#x5219;&#x4F1A;&#x81EA;&#x52A8;&#x542F;&#x52A8;&#x5E76;&#x914D;&#x7F6E;&#x4E00;&#x4E2A;&#x5185;&#x5D4C;&#x5F0F; broker&#xFF08;&#x524D;&#x63D0;&#x662F;&#x672A;&#x901A;&#x8FC7;&#x914D;&#x7F6E;&#x6307;&#x5B9A; broder URL&#xFF09;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x4F7F;&#x7528; <code>spring-boot-starter-activemq</code>&#xFF0C;&#x5219;&#x63D0;&#x4F9B;&#x4E86;&#x8FDE;&#x63A5;&#x5230; ActiveMQ &#x5B9E;&#x4F8B;&#x5FC5;&#x987B;&#x4F9D;&#x8D56;&#x6216;&#x5185;&#x5D4C;&#x4E00;&#x4E2A; ActiveMQ &#x5B9E;&#x4F8B;&#xFF0C;&#x4EE5;&#x53CA;&#x4E0E; JMS &#x96C6;&#x6210;&#x7684; Spring &#x57FA;&#x7840;&#x8BBE;&#x65BD;&#x3002;</p>
</blockquote>
<p>ActiveMQ &#x914D;&#x7F6E;&#x7531; <code>spring.activemq.*</code> &#x4E2D;&#x7684;&#x5916;&#x90E8;&#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x63A7;&#x5236;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>application.properties</code> &#x4E2D;&#x58F0;&#x660E;&#x4EE5;&#x4E0B;&#x90E8;&#x5206;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.activemq.broker-url</span><span class="token attr-value"><span class="token punctuation">=</span>tcp://192.168.1.210:9876</span>
<span class="token constant">spring.activemq.user</span><span class="token attr-value"><span class="token punctuation">=</span>admin</span>
<span class="token constant">spring.activemq.password</span><span class="token attr-value"><span class="token punctuation">=</span>secret</span>
</code></pre>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;<code>CachingConnectionFactory</code> &#x5C06;&#x539F;&#x751F;&#x7684; <code>ConnectionFactory</code> &#x4F7F;&#x7528;&#x53EF;&#x7531; <code>spring.jms.*</code> &#x4E2D;&#x7684;&#x5916;&#x90E8;&#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x63A7;&#x5236;&#x7684;&#x5408;&#x7406;&#x8BBE;&#x7F6E;&#x5305;&#x88C5;&#x8D77;&#x6765;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.jms.cache.session-cache-size</span><span class="token attr-value"><span class="token punctuation">=</span>5</span>
</code></pre>
<p>&#x5982;&#x679C;&#x60A8;&#x66F4;&#x613F;&#x610F;&#x4F7F;&#x7528;&#x539F;&#x751F;&#x6C60;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5411; <code>org.messaginghub:pooled-jms</code> &#x6DFB;&#x52A0;&#x4E00;&#x4E2A;&#x4F9D;&#x8D56;&#x5E76;&#x76F8;&#x5E94;&#x5730;&#x914D;&#x7F6E; <code>JmsPoolConnectionFactory</code> &#x6765;&#x5B9E;&#x73B0;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.activemq.pool.enabled</span><span class="token attr-value"><span class="token punctuation">=</span>true</span>
<span class="token constant">spring.activemq.pool.max-connections</span><span class="token attr-value"><span class="token punctuation">=</span>50</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6709;&#x5173;&#x66F4;&#x591A;&#x652F;&#x6301;&#x7684;&#x9009;&#x9879;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/activemq/ActiveMQProperties.java" target="_blank"><code>ActiveMQProperties</code></a>&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x6CE8;&#x518C;&#x591A;&#x4E2A;&#x5B9E;&#x73B0;&#x4E86; <code>ActiveMQConnectionFactoryCustomizer</code> &#x7684;&#x7684; bean&#xFF0C;&#x4EE5;&#x8FDB;&#x884C;&#x66F4;&#x9AD8;&#x7EA7;&#x7684;&#x81EA;&#x5B9A;&#x4E49;&#x3002;</p>
</blockquote>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;ActiveMQ &#x4F1A;&#x521B;&#x5EFA;&#x4E00;&#x4E2A; destination&#xFF08;&#x76EE;&#x6807;&#xFF09;&#xFF08;&#x5982;&#x679C;&#x5B83;&#x5C1A;&#x4E0D;&#x5B58;&#x5728;&#xFF09;&#xFF0C;&#x4EE5;&#x4FBF;&#x6839;&#x636E;&#x63D0;&#x4F9B;&#x7684;&#x540D;&#x79F0;&#x89E3;&#x6790; destination&#x3002;</p>
<p><a id="boot-features-artemis"></a></p>
<h4 id="3312&#x3001;artemis-&#x652F;&#x6301;">33.1.2&#x3001;Artemis &#x652F;&#x6301;</h4>
<p>Spring Boot &#x53EF;&#x4EE5;&#x5728;&#x68C0;&#x6D4B;&#x5230; <a href="http://activemq.apache.org/artemis/" target="_blank">Artemis</a> &#x5728; classpath &#x4E0A;&#x53EF;&#x7528;&#x65F6;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A; <code>ConnectionFactory</code>&#x3002;&#x5982;&#x679C;&#x5B58;&#x5728; broker&#xFF0C;&#x5219;&#x4F1A;&#x81EA;&#x52A8;&#x542F;&#x52A8;&#x5E76;&#x914D;&#x7F6E;&#x4E00;&#x4E2A;&#x5185;&#x5D4C; broker&#xFF08;&#x9664;&#x975E;&#x5DF2;&#x660E;&#x786E;&#x8BBE;&#x7F6E; mode &#x5C5E;&#x6027;&#xFF09;&#x3002;&#x652F;&#x6301;&#x7684; mode &#x4E3A; <code>embedded</code>&#xFF08;&#x660E;&#x786E;&#x8868;&#x793A;&#x9700;&#x8981;&#x4E00;&#x4E2A;&#x5185;&#x5D4C; broker&#xFF0C;&#x5982;&#x679C; broker &#x5728; classpath &#x4E0A;&#x4E0D;&#x53EF;&#x7528;&#x5219;&#x53D1;&#x751F;&#x9519;&#x8BEF;&#xFF09;&#x548C; <code>native</code>&#xFF08;&#x4F7F;&#x7528; netty &#x4F20;&#x8F93;&#x534F;&#x8BAE;&#x8FDE;&#x63A5;&#x5230; broker&#xFF09;&#x3002;&#x914D;&#x7F6E;&#x540E;&#x8005;&#x540E;&#xFF0C;Spring Boot &#x4F1A;&#x4F7F;&#x7528;&#x9ED8;&#x8BA4;&#x8BBE;&#x7F6E;&#x914D;&#x7F6E;&#x4E00;&#x4E2A; <code>ConnectionFactory</code>&#xFF0C;&#x8BE5; <code>ConnectionFactory</code> &#x8FDE;&#x63A5;&#x5230;&#x5728;&#x672C;&#x5730;&#x8BA1;&#x7B97;&#x673A;&#x4E0A;&#x8FD0;&#x884C;&#x7684; broker&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x4F7F;&#x7528;&#x4E86; <code>spring-boot-starter-artemis</code>&#xFF0C;&#x5219;&#x4F1A;&#x63D0;&#x4F9B;&#x8FDE;&#x63A5;&#x5230;&#x73B0;&#x6709;&#x7684; Artemis &#x5B9E;&#x4F8B;&#x7684;&#x5FC5;&#x987B;&#x4F9D;&#x8D56;&#xFF0C;&#x4EE5;&#x53CA;&#x4E0E; JMS &#x96C6;&#x6210;&#x7684;Spring &#x57FA;&#x7840;&#x8BBE;&#x65BD;&#x3002;&#x5C06; <code>org.apache.activemq:artemis-jms-server</code> &#x6DFB;&#x52A0;&#x5230;&#x60A8;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x53EF;&#x8BA9;&#x60A8;&#x4F7F;&#x7528;&#x5185;&#x5D4C;&#x6A21;&#x5F0F;&#x3002;</p>
</blockquote>
<p>Artemis &#x914D;&#x7F6E;&#x7531; <code>spring.artemis.*</code> &#x4E2D;&#x7684;&#x5916;&#x90E8;&#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x63A7;&#x5236;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>application.properties</code> &#x4E2D;&#x58F0;&#x660E;&#x4EE5;&#x4E0B;&#x90E8;&#x5206;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.artemis.mode</span><span class="token attr-value"><span class="token punctuation">=</span>native</span>
<span class="token constant">spring.artemis.host</span><span class="token attr-value"><span class="token punctuation">=</span>192.168.1.210</span>
<span class="token constant">spring.artemis.port</span><span class="token attr-value"><span class="token punctuation">=</span>9876</span>
<span class="token constant">spring.artemis.user</span><span class="token attr-value"><span class="token punctuation">=</span>admin</span>
<span class="token constant">spring.artemis.password</span><span class="token attr-value"><span class="token punctuation">=</span>secret</span>
</code></pre>
<p>&#x5185;&#x5D4C; broker &#x65F6;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x9009;&#x62E9;&#x662F;&#x5426;&#x8981;&#x542F;&#x7528;&#x6301;&#x4E45;&#x5316;&#x5E76;&#x5217;&#x51FA;&#x5E94;&#x8BE5;&#x53EF;&#x7528;&#x7684; destination&#x3002;&#x53EF;&#x4EE5;&#x5C06;&#x8FD9;&#x4E9B;&#x6307;&#x5B9A;&#x4E3A;&#x4EE5;&#x9017;&#x53F7;&#x5206;&#x9694;&#x7684;&#x5217;&#x8868;&#xFF0C;&#x4EE5;&#x4F7F;&#x7528;&#x9ED8;&#x8BA4;&#x9009;&#x9879;&#x521B;&#x5EFA;&#x5B83;&#x4EEC;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x5B9A;&#x4E49;&#x7C7B;&#x578B;&#x4E3A; <code>org.apache.activemq.artemis.jms.server.config.JMSQueueConfiguration</code> &#x6216; <code>org.apache.activemq.artemis.jms.server.config.TopicConfiguration</code> &#x7684; bean&#xFF0C;&#x5206;&#x522B;&#x7528;&#x4E8E;&#x9AD8;&#x7EA7;&#x961F;&#x5217;&#x548C; topic&#xFF08;&#x4E3B;&#x9898;&#xFF09;&#x914D;&#x7F6E;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;<code>CachingConnectionFactory</code> &#x5C06;&#x539F;&#x751F;&#x7684; <code>ConnectionFactory</code> &#x4F7F;&#x7528;&#x53EF;&#x7531; <code>spring.jms.*</code> &#x4E2D;&#x7684;&#x5916;&#x90E8;&#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x63A7;&#x5236;&#x7684;&#x5408;&#x7406;&#x8BBE;&#x7F6E;&#x5305;&#x88C5;&#x8D77;&#x6765;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.jms.cache.session-cache-size</span><span class="token attr-value"><span class="token punctuation">=</span>5</span>
</code></pre>
<p>&#x5982;&#x679C;&#x60A8;&#x66F4;&#x613F;&#x610F;&#x4F7F;&#x7528;&#x539F;&#x751F;&#x6C60;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5411; <code>org.messaginghub:pooled-jms</code> &#x6DFB;&#x52A0;&#x4E00;&#x4E2A;&#x4F9D;&#x8D56;&#x5E76;&#x76F8;&#x5E94;&#x5730;&#x914D;&#x7F6E; <code>JmsPoolConnectionFactory</code> &#x6765;&#x5B9E;&#x73B0;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.artemis.pool.enabled</span><span class="token attr-value"><span class="token punctuation">=</span>true</span>
<span class="token constant">spring.artemis.pool.max-connections</span><span class="token attr-value"><span class="token punctuation">=</span>50</span>
</code></pre>
<p>&#x6709;&#x5173;&#x66F4;&#x591A;&#x652F;&#x6301;&#x7684;&#x9009;&#x9879;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jms/artemis/ArtemisProperties.java" target="_blank"><code>ArtemisProperties</code></a>&#x3002;</p>
<p>&#x4E0D;&#x6D89;&#x53CA; JNDI &#x67E5;&#x627E;&#xFF0C;&#x4F7F;&#x7528; Artemis &#x914D;&#x7F6E;&#x4E2D;&#x7684; <code>name</code> &#x5C5E;&#x6027;&#x6216;&#x901A;&#x8FC7;&#x914D;&#x7F6E;&#x63D0;&#x4F9B;&#x7684;&#x540D;&#x79F0;&#x6765;&#x89E3;&#x6790;&#x76EE;&#x6807;&#xFF08;destination&#xFF09;&#x540D;&#x79F0;&#x3002;</p>
<p><a id="boot-features-jms-jndi"></a></p>
<h4 id="3313&#x3001;&#x4F7F;&#x7528;-jndi-connectionfactory">33.1.3&#x3001;&#x4F7F;&#x7528; JNDI ConnectionFactory</h4>
<p>&#x5982;&#x679C;&#x60A8;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x670D;&#x52A1;&#x5668;&#x4E2D;&#x8FD0;&#x884C;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;Spring Boot &#x4F1A;&#x5C1D;&#x8BD5;&#x4F7F;&#x7528; JNDI &#x627E;&#x5230; JMS <code>ConnectionFactory</code>&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5C06;&#x68C0;&#x67E5; <code>java:/JmsXA</code> &#x548C; <code>java:/XAConnectionFactory</code> &#x8FD9;&#x4E24;&#x4E2A;&#x4F4D;&#x7F6E;&#x3002;&#x5982;&#x679C;&#x9700;&#x8981;&#x6307;&#x5B9A;&#x5176;&#x4ED6;&#x4F4D;&#x7F6E;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.jms.jndi-name</code> &#x5C5E;&#x6027;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.jms.jndi-name</span><span class="token attr-value"><span class="token punctuation">=</span>java:/MyConnectionFactory</span>
</code></pre>
<p><a id="boot-features-using-jms-sending"></a></p>
<h4 id="3314&#x3001;&#x53D1;&#x9001;&#x6D88;&#x606F;">33.1.4&#x3001;&#x53D1;&#x9001;&#x6D88;&#x606F;</h4>
<p>Spring &#x7684; <code>JmsTemplate</code> &#x662F;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684;&#xFF0C;&#x4F60;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x5C06;&#x5B83;&#x6CE8;&#x5165;&#x5230;&#x4F60;&#x81EA;&#x5DF1;&#x7684; bean &#x4E2D;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation</span><span class="token punctuation">.</span><span class="token class-name">Autowired</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>jms<span class="token punctuation">.</span>core</span><span class="token punctuation">.</span><span class="token class-name">JmsTemplate</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype</span><span class="token punctuation">.</span><span class="token class-name">Component</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">JmsTemplate</span> jmsTemplate<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">JmsTemplate</span> jmsTemplate<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>jmsTemplate <span class="token operator">=</span> jmsTemplate<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p><code>JmsMessagingTemplate</code> &#x53EF;&#x4EE5;&#x4EE5;&#x7C7B;&#x4F3C;&#x7684;&#x65B9;&#x5F0F;&#x6CE8;&#x5165;&#x3002;&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86; <code>DestinationResolver</code> &#x6216; <code>MessageConverter</code> bean&#xFF0C;&#x5B83;&#x5C06;&#x81EA;&#x52A8;&#x5173;&#x8054;&#x5230;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>JmsTemplate</code>&#x3002;</p>
</blockquote>
<p><a id="boot-features-using-jms-receiving"></a></p>
<h4 id="3315&#x3001;&#x63A5;&#x6536;&#x6D88;&#x606F;">33.1.5&#x3001;&#x63A5;&#x6536;&#x6D88;&#x606F;</h4>
<p>&#x5F53;&#x5B58;&#x5728; JMS &#x57FA;&#x7840;&#x8BBE;&#x65BD;&#x65F6;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@JmsListener</code> &#x5BF9;&#x4EFB;&#x4F55; bean &#x8FDB;&#x884C;&#x6CE8;&#x89E3;&#x4EE5;&#x521B;&#x5EFA;&#x76D1;&#x542C;&#x5668;&#xFF08;listener&#xFF09;&#x7AEF;&#x70B9;&#x3002;&#x5982;&#x679C;&#x672A;&#x5B9A;&#x4E49; <code>JmsListenerContainerFactory</code>&#xFF0C;&#x5219;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A;&#x9ED8;&#x8BA4;&#x7684;&#xFF08;factory&#xFF09;&#x3002;&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86; <code>DestinationResolver</code> &#x6216; <code>MessageConverter</code> bean&#xFF0C;&#x5B83;&#x5C06;&#x81EA;&#x52A8;&#x5173;&#x8054;&#x5230;&#x9ED8;&#x8BA4;&#x7684; factory&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x9ED8;&#x8BA4; factory &#x662F;&#x5177;&#x6709;&#x4E8B;&#x52A1;&#x7279;&#x6027;&#x7684;&#x3002;&#x5982;&#x679C;&#x60A8;&#x5728;&#x5B58;&#x5728;&#x6709; <code>JtaTransactionManager</code> &#x7684;&#x57FA;&#x7840;&#x8BBE;&#x65BD;&#x4E2D;&#x8FD0;&#x884C;&#xFF0C;&#x5219;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#x5B83;&#x4E0E;&#x76D1;&#x542C;&#x5668;&#x5BB9;&#x5668;&#x76F8;&#x5173;&#x8054;&#x3002;&#x5982;&#x679C;&#x4E0D;&#x662F;&#xFF0C;&#x5219; <code>sessionTransacted</code> flag &#x5C06;&#x4E3A;&#x542F;&#x7528;&#xFF08;enabled&#xFF09;&#x3002;&#x5728;&#x540E;&#x4E00;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5728;&#x76D1;&#x542C;&#x5668;&#x65B9;&#x6CD5;&#xFF08;&#x6216;&#x5176;&#x59D4;&#x6258;&#xFF09;&#x4E0A;&#x6DFB;&#x52A0; <code>@Transactional</code>&#xFF0C;&#x5C06;&#x672C;&#x5730;&#x6570;&#x636E;&#x5B58;&#x50A8;&#x4E8B;&#x52A1;&#x4E0E;&#x4F20;&#x5165;&#x6D88;&#x606F;&#x7684;&#x5904;&#x7406;&#x76F8;&#x5173;&#x8054;&#x3002;&#x8FD9;&#x786E;&#x4FDD;&#x4E86;&#x5728;&#x672C;&#x5730;&#x4E8B;&#x52A1;&#x5B8C;&#x6210;&#x540E;&#x4F20;&#x5165;&#x6D88;&#x606F;&#x80FD;&#x88AB;&#x544A;&#x77E5;&#x3002;&#x8FD9;&#x8FD8;&#x5305;&#x62EC;&#x4E86;&#x53D1;&#x9001;&#x5DF2;&#x5728;&#x540C;&#x4E00; JMS &#x4F1A;&#x8BDD;&#x4E0A;&#x6267;&#x884C;&#x7684;&#x54CD;&#x5E94;&#x6D88;&#x606F;&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x7EC4;&#x4EF6;&#x5728; <code>someQueue</code> destination &#x4E0A;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x76D1;&#x542C;&#x5668;&#x7AEF;&#x70B9;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@JmsListener</span><span class="token punctuation">(</span>destination <span class="token operator">=</span> <span class="token string">&quot;someQueue&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">processMessage</span><span class="token punctuation">(</span><span class="token class-name">String</span> content<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6709;&#x5173;&#x66F4;&#x591A;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/jms/annotation/EnableJms.html" target="_blank"><code>@EnableJms</code> &#x7684; Javadoc</a>&#x3002;</p>
</blockquote>
<p>&#x5982;&#x679C;&#x9700;&#x8981;&#x521B;&#x5EFA;&#x66F4;&#x591A; <code>JmsListenerContainerFactory</code> &#x5B9E;&#x4F8B;&#x6216;&#x8986;&#x76D6;&#x7F3A;&#x7701;&#x503C;&#xFF0C;Spring Boot &#x4F1A;&#x63D0;&#x4F9B;&#x4E00;&#x4E2A; <code>DefaultJmsListenerContainerFactoryConfigurer</code>&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x5B83;&#x6765;&#x521D;&#x59CB;&#x5316; <code>DefaultJmsListenerContainerFactory</code>&#xFF0C;&#x5176;&#x8BBE;&#x7F6E;&#x4E0E;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; factory &#x8BBE;&#x7F6E;&#x76F8;&#x540C;&#x3002;</p>
<p>&#x4F8B;&#x5982;&#xFF0C;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x66B4;&#x9732;&#x4E86;&#x53E6;&#x4E00;&#x4E2A;&#x4F7F;&#x7528;&#x7279;&#x5B9A; <code>MessageConverter</code> &#x7684; factory&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">JmsConfiguration</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">DefaultJmsListenerContainerFactory</span> <span class="token function">myFactory</span><span class="token punctuation">(</span>
            <span class="token class-name">DefaultJmsListenerContainerFactoryConfigurer</span> configurer<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">DefaultJmsListenerContainerFactory</span> factory <span class="token operator">=</span>
                <span class="token keyword">new</span> <span class="token class-name">DefaultJmsListenerContainerFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        configurer<span class="token punctuation">.</span><span class="token function">configure</span><span class="token punctuation">(</span>factory<span class="token punctuation">,</span> <span class="token function">connectionFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        factory<span class="token punctuation">.</span><span class="token function">setMessageConverter</span><span class="token punctuation">(</span><span class="token function">myMessageConverter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> factory<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x7136;&#x540E;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728;&#x4EFB;&#x4F55; <code>@JmsListener</code> &#x6CE8;&#x89E3;&#x7684;&#x65B9;&#x6CD5;&#x4E2D;&#x4F7F;&#x7528;&#x8BE5; factory&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@JmsListener</span><span class="token punctuation">(</span>destination <span class="token operator">=</span> <span class="token string">&quot;someQueue&quot;</span><span class="token punctuation">,</span> containerFactory<span class="token operator">=</span><span class="token string">&quot;myFactory&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">processMessage</span><span class="token punctuation">(</span><span class="token class-name">String</span> content<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-amqp"></a></p>
<h3 id="332&#x3001;amqp">33.2&#x3001;AMQP</h3>
<p>&#x9AD8;&#x7EA7;&#x6D88;&#x606F;&#x961F;&#x5217;&#x534F;&#x8BAE;&#xFF08;Advanced Message Queuing Protocol&#xFF0C;AMQP&#xFF09;&#x662F;&#x4E00;&#x4E2A;&#x5E73;&#x53F0;&#x65E0;&#x5173;&#xFF0C;&#x9762;&#x5411;&#x6D88;&#x606F;&#x4E2D;&#x95F4;&#x4EF6;&#x7684;&#x8FDE;&#x63A5;&#x7EA7;&#x534F;&#x8BAE;&#x3002;Spring AMQP &#x9879;&#x76EE;&#x5C06;&#x6838;&#x5FC3; Spring &#x6982;&#x5FF5;&#x5E94;&#x7528;&#x4E8E;&#x57FA;&#x4E8E; AMQP &#x6D88;&#x606F;&#x4F20;&#x9012;&#x89E3;&#x51B3;&#x65B9;&#x6848;&#x7684;&#x5F00;&#x53D1;&#x3002;Spring Boot &#x4E3A;&#x901A;&#x8FC7; RabbitMQ &#x4F7F;&#x7528; AMQP &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E9B;&#x5FEB;&#x6377;&#x65B9;&#x6CD5;&#xFF0C;&#x5305;&#x62EC; <code>spring-boot-starter-amqp</code> starter&#x3002;</p>
<p><a id="boot-features-rabbitmq"></a></p>
<h4 id="3321&#x3001;rabbitmq-&#x652F;&#x6301;">33.2.1&#x3001;RabbitMQ &#x652F;&#x6301;</h4>
<p><a href="https://www.rabbitmq.com/" target="_blank">RabbitMQ</a> &#x662F;&#x4E00;&#x4E2A;&#x57FA;&#x4E8E; AMQP &#x534F;&#x8BAE;&#x7684;&#x8F7B;&#x91CF;&#x7EA7;&#x3001;&#x53EF;&#x9760;&#x3001;&#x53EF;&#x6269;&#x5C55;&#x4E14;&#x53EF;&#x79FB;&#x690D;&#x7684;&#x6D88;&#x606F;&#x4EE3;&#x7406;&#x3002;Spring &#x4F7F;&#x7528; RabbitMQ &#x901A;&#x8FC7; AMQP &#x534F;&#x8BAE;&#x8FDB;&#x884C;&#x901A;&#x4FE1;&#x3002;</p>
<p>RabbitMQ &#x914D;&#x7F6E;&#x7531; <code>spring.rabbitmq.*</code> &#x4E2D;&#x7684;&#x5916;&#x90E8;&#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x63A7;&#x5236;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>application.properties</code> &#x4E2D;&#x58F0;&#x660E;&#x4EE5;&#x4E0B;&#x90E8;&#x5206;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.rabbitmq.host</span><span class="token attr-value"><span class="token punctuation">=</span>localhost</span>
<span class="token constant">spring.rabbitmq.port</span><span class="token attr-value"><span class="token punctuation">=</span>5672</span>
<span class="token constant">spring.rabbitmq.username</span><span class="token attr-value"><span class="token punctuation">=</span>admin</span>
<span class="token constant">spring.rabbitmq.password</span><span class="token attr-value"><span class="token punctuation">=</span>secret</span>
</code></pre>
<p>&#x5982;&#x679C;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x5B58;&#x5728; <code>ConnectionNameStrategy</code> bean&#xFF0C;&#x5B83;&#x5C06;&#x81EA;&#x52A8;&#x7528;&#x4E8E;&#x547D;&#x540D;&#x7531;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>ConnectionFactory</code> &#x6240;&#x521B;&#x5EFA;&#x7684;&#x8FDE;&#x63A5;&#x3002;&#x6709;&#x5173;&#x66F4;&#x591A;&#x652F;&#x6301;&#x7684;&#x9009;&#x9879;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java" target="_blank">RabbitProperties</a>&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605;<a href="https://spring.io/blog/2010/06/14/understanding-amqp-the-protocol-used-by-rabbitmq/" target="_blank">&#x7406;&#x89E3; AMQP&#x3001;RabbitMQ &#x4F7F;&#x7528;&#x7684;&#x534F;&#x8BAE;</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-using-amqp-sending"></a></p>
<h4 id="3322&#x3001;&#x53D1;&#x9001;&#x6D88;&#x606F;">33.2.2&#x3001;&#x53D1;&#x9001;&#x6D88;&#x606F;</h4>
<p>Spring &#x7684; <code>AmqpTemplate</code> &#x548C; <code>AmqpAdmin</code> &#x662F;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5C06;&#x5B83;&#x4EEC;&#x76F4;&#x63A5;&#x6CE8;&#x5165;&#x81EA;&#x5DF1;&#x7684; bean &#x4E2D;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>amqp<span class="token punctuation">.</span>core</span><span class="token punctuation">.</span><span class="token class-name">AmqpAdmin</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>amqp<span class="token punctuation">.</span>core</span><span class="token punctuation">.</span><span class="token class-name">AmqpTemplate</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>beans<span class="token punctuation">.</span>factory<span class="token punctuation">.</span>annotation</span><span class="token punctuation">.</span><span class="token class-name">Autowired</span><span class="token punctuation">;</span>
<span class="token keyword">import</span> <span class="token namespace">org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>stereotype</span><span class="token punctuation">.</span><span class="token class-name">Component</span><span class="token punctuation">;</span>

<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">AmqpAdmin</span> amqpAdmin<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">AmqpTemplate</span> amqpTemplate<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">AmqpAdmin</span> amqpAdmin<span class="token punctuation">,</span> <span class="token class-name">AmqpTemplate</span> amqpTemplate<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>amqpAdmin <span class="token operator">=</span> amqpAdmin<span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>amqpTemplate <span class="token operator">=</span> amqpTemplate<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>RabbitMessagingTemplate &#x53EF;&#x4EE5;&#x4EE5;&#x7C7B;&#x4F3C;&#x7684;&#x65B9;&#x5F0F;&#x6CE8;&#x5165;&#x3002;&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86; <code>MessageConverter</code> bean&#xFF0C;&#x5B83;&#x5C06;&#x81EA;&#x52A8;&#x5173;&#x8054;&#x5230;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>AmqpTemplate</code>&#x3002;</p>
</blockquote>
<p>&#x5982;&#x6709;&#x5FC5;&#x8981;&#xFF0C;&#x6240;&#x6709;&#x5B9A;&#x4E49;&#x4E3A; bean &#x7684; <code>org.springframework.amqp.core.Queue</code> &#x90FD;&#x4F1A;&#x81EA;&#x52A8;&#x5728; RabbitMQ &#x5B9E;&#x4F8B;&#x4E0A;&#x58F0;&#x660E;&#x76F8;&#x5E94;&#x7684;&#x961F;&#x5217;&#x3002;</p>
<p>&#x8981;&#x91CD;&#x8BD5;&#x64CD;&#x4F5C;&#xFF0C;&#x53EF;&#x4EE5;&#x5728; <code>AmqpTemplate</code> &#x4E0A;&#x542F;&#x7528;&#x91CD;&#x8BD5;&#xFF08;&#x4F8B;&#x5982;&#xFF0C;&#x5728; broker &#x8FDE;&#x63A5;&#x4E22;&#x5931;&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#xFF09;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.rabbitmq.template.retry.enabled</span><span class="token attr-value"><span class="token punctuation">=</span>true</span>
<span class="token constant">spring.rabbitmq.template.retry.initial-interval</span><span class="token attr-value"><span class="token punctuation">=</span>2s</span>
</code></pre>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#x7981;&#x7528;&#x91CD;&#x8BD5;&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x58F0;&#x660E; <code>RabbitRetryTemplateCustomizer</code> bean &#x4EE5;&#x7F16;&#x7A0B;&#x65B9;&#x5F0F;&#x81EA;&#x5B9A;&#x4E49; <code>RetryTemplate</code>&#x3002;</p>
<p><a id="boot-features-using-amqp-receiving"></a></p>
<h4 id="3323&#x3001;&#x63A5;&#x6536;&#x6D88;&#x606F;">33.2.3&#x3001;&#x63A5;&#x6536;&#x6D88;&#x606F;</h4>
<p>&#x5F53; Rabbit &#x57FA;&#x7840;&#x8BBE;&#x65BD;&#x5B58;&#x5728;&#x65F6;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@RabbitListener</code> &#x6CE8;&#x89E3;&#x4EFB;&#x4F55; bean &#x4EE5;&#x521B;&#x5EFA;&#x76D1;&#x542C;&#x5668;&#x7AEF;&#x70B9;&#x3002;&#x5982;&#x679C;&#x672A;&#x5B9A;&#x4E49; <code>RabbitListenerContainerFactory</code>&#xFF0C;&#x5219;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A;&#x9ED8;&#x8BA4;&#x7684; <code>SimpleRabbitListenerContainerFactory</code>&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.rabbitmq.listener.type</code> &#x5C5E;&#x6027;&#x5207;&#x6362;&#x5230;&#x4E00;&#x4E2A;&#x76F4;&#x63A5;&#x5BB9;&#x5668;&#x3002;&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86; <code>MessageConverter</code> &#x6216; <code>MessageRecoverer</code> bean&#xFF0C;&#x5B83;&#x5C06;&#x81EA;&#x52A8;&#x4E0E;&#x9ED8;&#x8BA4; factory &#x5173;&#x8054;&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x7EC4;&#x4EF6;&#x5728; <code>someQueue</code> &#x961F;&#x5217;&#x4E0A;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x4FA6;&#x542C;&#x76D1;&#x542C;&#x5668;&#x7AEF;&#x70B9;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@RabbitListener</span><span class="token punctuation">(</span>queues <span class="token operator">=</span> <span class="token string">&quot;someQueue&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">processMessage</span><span class="token punctuation">(</span><span class="token class-name">String</span> content<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6709;&#x5173;&#x66F4;&#x591A;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://docs.spring.io/spring-amqp/docs/current/api/org/springframework/amqp/rabbit/annotation/EnableRabbit.html" target="_blank"><code>@EnableRabbit</code> &#x7684; Javadoc</a>&#x3002;</p>
</blockquote>
<p>&#x5982;&#x679C;&#x9700;&#x8981;&#x521B;&#x5EFA;&#x66F4;&#x591A; <code>RabbitListenerContainerFactory</code> &#x5B9E;&#x4F8B;&#x6216;&#x8986;&#x76D6;&#x7F3A;&#x7701;&#x503C;&#xFF0C;Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A; <code>SimpleRabbitListenerContainerFactoryConfigurer</code> &#x548C;&#x4E00;&#x4E2A; <code>DirectRabbitListenerContainerFactoryConfigurer</code>&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x5B83;&#x6765;&#x521D;&#x59CB;&#x5316; <code>SimpleRabbitListenerContainerFactory</code> &#x548C; <code>DirectRabbitListenerContainerFactory</code>&#xFF0C;&#x5176;&#x8BBE;&#x7F6E;&#x4E0E;&#x4F7F;&#x7528;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; factory &#x76F8;&#x540C;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x8FD9;&#x4E24;&#x4E2A; bean &#x4E0E;&#x60A8;&#x9009;&#x62E9;&#x7684;&#x5BB9;&#x5668;&#x7C7B;&#x578B;&#x6CA1;&#x6709;&#x5173;&#x7CFB;&#xFF0C;&#x5B83;&#x4EEC;&#x901A;&#x8FC7;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x66B4;&#x9732;&#x3002;</p>
</blockquote>
<p>&#x4F8B;&#x5982;&#xFF0C;&#x4EE5;&#x4E0B;&#x914D;&#x7F6E;&#x7C7B;&#x66B4;&#x9732;&#x4E86;&#x53E6;&#x4E00;&#x4E2A;&#x4F7F;&#x7528;&#x7279;&#x5B9A; <code>MessageConverter</code> &#x7684; factory&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">RabbitConfiguration</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">SimpleRabbitListenerContainerFactory</span> <span class="token function">myFactory</span><span class="token punctuation">(</span>
            <span class="token class-name">SimpleRabbitListenerContainerFactoryConfigurer</span> configurer<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">SimpleRabbitListenerContainerFactory</span> factory <span class="token operator">=</span>
                <span class="token keyword">new</span> <span class="token class-name">SimpleRabbitListenerContainerFactory</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        configurer<span class="token punctuation">.</span><span class="token function">configure</span><span class="token punctuation">(</span>factory<span class="token punctuation">,</span> connectionFactory<span class="token punctuation">)</span><span class="token punctuation">;</span>
        factory<span class="token punctuation">.</span><span class="token function">setMessageConverter</span><span class="token punctuation">(</span><span class="token function">myMessageConverter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> factory<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x7136;&#x540E;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728;&#x4EFB;&#x4F55; <code>@RabbitListener</code> &#x6CE8;&#x89E3;&#x7684;&#x65B9;&#x6CD5;&#x4E2D;&#x4F7F;&#x7528;&#x8BE5; factory&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@RabbitListener</span><span class="token punctuation">(</span>queues <span class="token operator">=</span> <span class="token string">&quot;someQueue&quot;</span><span class="token punctuation">,</span> containerFactory<span class="token operator">=</span><span class="token string">&quot;myFactory&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">processMessage</span><span class="token punctuation">(</span><span class="token class-name">String</span> content<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x542F;&#x7528;&#x91CD;&#x8BD5;&#x673A;&#x5236;&#x6765;&#x5904;&#x7406;&#x76D1;&#x542C;&#x5668;&#x7684;&#x5F02;&#x5E38;&#x629B;&#x51FA;&#x60C5;&#x51B5;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#x4F7F;&#x7528; <code>RejectAndDontRequeueRecoverer</code>&#xFF0C;&#x4F46;&#x60A8;&#x53EF;&#x4EE5;&#x5B9A;&#x4E49;&#x81EA;&#x5DF1;&#x7684; <code>MessageRecoverer</code>&#x3002;&#x5982;&#x679C; broker &#x914D;&#x7F6E;&#x4E86;&#x91CD;&#x8BD5;&#x673A;&#x5236;&#xFF0C;&#x5F53;&#x91CD;&#x8BD5;&#x6B21;&#x6570;&#x8017;&#x5C3D;&#x65F6;&#xFF0C;&#x5219;&#x62D2;&#x7EDD;&#x6D88;&#x606F;&#x5E76;&#x5C06;&#x5176;&#x4E22;&#x5F03;&#x6216;&#x8DEF;&#x7531;&#x5230;&#x6B7B;&#x4FE1;&#xFF08;dead-letter&#xFF09;exchange &#x4E2D;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#x91CD;&#x8BD5;&#x673A;&#x5236;&#x4E3A;&#x7981;&#x7528;&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x58F0;&#x660E; <code>RabbitRetryTemplateCustomizer</code> bean &#x4EE5;&#x7F16;&#x7A0B;&#x65B9;&#x5F0F;&#x81EA;&#x5B9A;&#x4E49; <code>RetryTemplate</code>&#x3002;</p>
<p><strong>&#x91CD;&#x8981;</strong></p>
<blockquote>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5982;&#x679C;&#x7981;&#x7528;&#x91CD;&#x8BD5;&#x5E76;&#x4E14;&#x76D1;&#x542C;&#x5668;&#x5F02;&#x5E38;&#x629B;&#x51FA;&#xFF0C;&#x5219;&#x4F1A;&#x65E0;&#x9650;&#x671F;&#x5730;&#x91CD;&#x8BD5;&#x4F20;&#x9012;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4E24;&#x79CD;&#x65B9;&#x5F0F;&#x4FEE;&#x6539;&#x6B64;&#x884C;&#x4E3A;&#xFF1A;&#x5C06; <code>defaultRequeueRejected</code> &#x5C5E;&#x6027;&#x8BBE;&#x7F6E;&#x4E3A; <code>false</code>&#xFF0C;&#x4EE5;&#x4FBF;&#x5C1D;&#x8BD5;&#x96F6;&#x91CD;&#x4F20;&#x6216;&#x629B;&#x51FA; <code>AmqpRejectAndDontRequeueException</code> &#x4EE5;&#x6307;&#x793A;&#x62D2;&#x7EDD;&#x8BE5;&#x6D88;&#x606F;&#x3002;&#x540E;&#x8005;&#x662F;&#x542F;&#x7528;&#x91CD;&#x8BD5;&#x5E76;&#x4E14;&#x8FBE;&#x5230;&#x6700;&#x5927;&#x4F20;&#x9012;&#x5C1D;&#x8BD5;&#x6B21;&#x6570;&#x65F6;&#x4F7F;&#x7528;&#x7684;&#x673A;&#x5236;&#x3002;</p>
</blockquote>
<p><a id="boot-features-kafka"></a></p>
<h3 id="333&#x3001;apache-kafka-&#x652F;&#x6301;">33.3&#x3001;Apache Kafka &#x652F;&#x6301;</h3>
<p>&#x901A;&#x8FC7;&#x63D0;&#x4F9B; <code>spring-kafka</code> &#x9879;&#x76EE;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x6765;&#x652F;&#x6301; <a href="https://kafka.apache.org/" target="_blank">Apache Kafka</a>&#x3002;</p>
<p>Kafka &#x914D;&#x7F6E;&#x7531; <code>spring.kafka.*</code> &#x4E2D;&#x7684;&#x5916;&#x90E8;&#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x63A7;&#x5236;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <code>application.properties</code> &#x4E2D;&#x58F0;&#x660E;&#x4EE5;&#x4E0B;&#x90E8;&#x5206;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.kafka.bootstrap-servers</span><span class="token attr-value"><span class="token punctuation">=</span>localhost:9092</span>
<span class="token constant">spring.kafka.consumer.group-id</span><span class="token attr-value"><span class="token punctuation">=</span>myGroup</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x8981;&#x5728;&#x542F;&#x52A8;&#x65F6;&#x521B;&#x5EFA;&#x4E3B;&#x9898;&#xFF08;topic&#xFF09;&#xFF0C;&#x8BF7;&#x6DFB;&#x52A0; <code>NewTopic</code> &#x7C7B;&#x578B;&#x7684; Bean&#x3002;&#x5982;&#x679C;&#x4E3B;&#x9898;&#x5DF2;&#x5B58;&#x5728;&#xFF0C;&#x5219;&#x5FFD;&#x7565;&#x8BE5; bean&#x3002;</p>
</blockquote>
<p>&#x6709;&#x5173;&#x66F4;&#x591A;&#x652F;&#x6301;&#x7684;&#x9009;&#x9879;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/kafka/KafkaProperties.java" target="_blank"><code>KafkaProperties</code></a>&#x3002;</p>
<p><a id="boot-features-kafka-sending-a-message"></a></p>
<h4 id="3331&#x3001;&#x53D1;&#x9001;&#x6D88;&#x606F;">33.3.1&#x3001;&#x53D1;&#x9001;&#x6D88;&#x606F;</h4>
<p>Spring &#x7684; <code>KafkaTemplate</code> &#x662F;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x5728;&#x81EA;&#x5DF1;&#x7684; bean &#x4E2D;&#x88C5;&#x914D;&#x5B83;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">KafkaTemplate</span> kafkaTemplate<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">public</span> <span class="token class-name">MyBean</span><span class="token punctuation">(</span><span class="token class-name">KafkaTemplate</span> kafkaTemplate<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>kafkaTemplate <span class="token operator">=</span> kafkaTemplate<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment">// ...</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86;&#x5C5E;&#x6027; <code>spring.kafka.producer.transaction-id-prefix</code>&#xFF0C;&#x5219;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A; <code>KafkaTransactionManager</code>&#x3002;&#x6B64;&#x5916;&#xFF0C;&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86; <code>RecordMessageConverter</code> bean&#xFF0C;&#x5B83;&#x5C06;&#x81EA;&#x52A8;&#x5173;&#x8054;&#x5230;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>KafkaTemplate</code>&#x3002;</p>
</blockquote>
<p><a id="boot-features-kafka-receiving-a-message"></a></p>
<h4 id="3332&#x3001;&#x63A5;&#x6536;&#x6D88;&#x606F;">33.3.2&#x3001;&#x63A5;&#x6536;&#x6D88;&#x606F;</h4>
<p>&#x5F53;&#x5B58;&#x5728; Apache Kafka &#x57FA;&#x7840;&#x8BBE;&#x65BD;&#x65F6;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@KafkaListener</code> &#x6CE8;&#x89E3;&#x4EFB;&#x4F55; bean &#x4EE5;&#x521B;&#x76D1;&#x542C;&#x5668;&#x7AEF;&#x70B9;&#x3002;&#x5982;&#x679C;&#x672A;&#x5B9A;&#x4E49; <code>KafkaListenerContainerFactory</code>&#xFF0C;&#x5219;&#x4F1A;&#x4F7F;&#x7528; <code>spring.kafka.listener.*</code> &#x4E2D;&#x5B9A;&#x4E49;&#x7684; key &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A;&#x9ED8;&#x8BA4;&#x7684; factory&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x7EC4;&#x4EF6;&#x5728; <code>someTopic</code> topic &#x4E0A;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x76D1;&#x542C;&#x5668;&#x7AEF;&#x70B9;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@KafkaListener</span><span class="token punctuation">(</span>topics <span class="token operator">=</span> <span class="token string">&quot;someTopic&quot;</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">processMessage</span><span class="token punctuation">(</span><span class="token class-name">String</span> content<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment">// ...</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86; <code>KafkaTransactionManager</code> bean&#xFF0C;&#x5B83;&#x5C06;&#x81EA;&#x52A8;&#x5173;&#x8054;&#x5230;&#x5BB9;&#x5668; factory&#x3002;&#x540C;&#x6837;&#xFF0C;&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86; <code>RecordMessageConverter</code>&#x3001;<code>ErrorHandler</code> &#x6216; <code>AfterRollbackProcessor</code> bean&#xFF0C;&#x5B83;&#x5C06;&#x81EA;&#x52A8;&#x5173;&#x8054;&#x5230;&#x9ED8;&#x8BA4;&#x7684; factory&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x81EA;&#x5B9A;&#x4E49; <code>ChainedKafkaTransactionManager</code> &#x5FC5;&#x987B;&#x6807;&#x8BB0;&#x4E3A; <code>@Primary</code>&#xFF0C;&#x56E0;&#x4E3A;&#x5B83;&#x901A;&#x5E38;&#x5F15;&#x7528;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>KafkaTransactionManager</code> bean&#x3002;</p>
</blockquote>
<p><a id="boot-features-kafka-streams"></a></p>
<h3 id="3333&#x3001;kafka-stream">33.3.3&#x3001;Kafka Stream</h3>
<p>Spring for Apache Kafka &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x5DE5;&#x5382; bean &#x6765;&#x521B;&#x5EFA; <code>StreamsBuilder</code> &#x5BF9;&#x8C61;&#x5E76;&#x7BA1;&#x7406;&#x5176; stream&#xFF08;&#x6D41;&#xFF09;&#x7684;&#x751F;&#x547D;&#x5468;&#x671F;&#x3002;&#x53EA;&#x8981; <code>kafka-streams</code> &#x5728; classpath &#x4E0A;&#x5E76;&#x4E14;&#x901A;&#x8FC7; <code>@EnableKafkaStreams</code> &#x6CE8;&#x89E3;&#x542F;&#x7528;&#x4E86; Kafka Stream&#xFF0C;Spring Boot &#x5C31;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x6240;&#x9700;&#x7684; <code>KafkaStreamsConfiguration</code> bean&#x3002;</p>
<p>&#x542F;&#x7528; Kafka Stream &#x610F;&#x5473;&#x7740;&#x5FC5;&#x987B;&#x8BBE;&#x7F6E;&#x5E94;&#x7528;&#x7A0B;&#x5E8F; id &#x548C;&#x5F15;&#x5BFC;&#x670D;&#x52A1;&#x5668;&#xFF08;bootstrap server&#xFF09;&#x3002;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.kafka.streams.application-id</code> &#x914D;&#x7F6E;&#x524D;&#x8005;&#xFF0C;&#x5982;&#x679C;&#x672A;&#x8BBE;&#x7F6E;&#x5219;&#x9ED8;&#x8BA4;&#x4E3A; <code>spring.application.name</code>&#x3002;&#x540E;&#x8005;&#x53EF;&#x4EE5;&#x5168;&#x5C40;&#x8BBE;&#x7F6E;&#x6216;&#x4E13;&#x95E8;&#x4E3A; stream &#x800C;&#x91CD;&#x5199;&#x3002;</p>
<p>&#x4F7F;&#x7528;&#x4E13;&#x7528; properties &#x53EF;&#x4EE5;&#x8BBE;&#x7F6E;&#x591A;&#x4E2A;&#x5176;&#x4ED6;&#x5C5E;&#x6027;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.kafka.streams.properties</code> &#x547D;&#x540D;&#x7A7A;&#x95F4;&#x8BBE;&#x7F6E;&#x5176;&#x4ED6;&#x4EFB;&#x610F; Kafka &#x5C5E;&#x6027;&#x3002;&#x6709;&#x5173;&#x66F4;&#x591A;&#x4FE1;&#x606F;&#xFF0C;&#x53E6;&#x8BF7;&#x53C2;&#x89C1;<a href="#boot-features-kafka-extra-props">&#x7B2C; 33.3.4 &#x8282;&#xFF1A;&#x5176;&#x4ED6; Kafka &#x5C5E;&#x6027;</a>&#x3002;</p>
<p>&#x8981;&#x4F7F;&#x7528; factory bean&#xFF0C;&#x53EA;&#x9700;&#x5C06; <code>StreamsBuilder</code> &#x88C5;&#x914D;&#x5230;&#x60A8;&#x7684; <code>@Bean</code> &#x4E2D;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token annotation punctuation">@EnableKafkaStreams</span>
<span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">KafkaStreamsExampleConfiguration</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">KStream</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Integer</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> <span class="token function">kStream</span><span class="token punctuation">(</span><span class="token class-name">StreamsBuilder</span> streamsBuilder<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">KStream</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Integer</span><span class="token punctuation">,</span> <span class="token class-name">String</span><span class="token punctuation">&gt;</span></span> stream <span class="token operator">=</span> streamsBuilder<span class="token punctuation">.</span><span class="token function">stream</span><span class="token punctuation">(</span><span class="token string">&quot;ks1In&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        stream<span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span><span class="token punctuation">(</span>k<span class="token punctuation">,</span> v<span class="token punctuation">)</span> <span class="token operator">-&gt;</span> <span class="token keyword">new</span> <span class="token class-name">KeyValue</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span>k<span class="token punctuation">,</span> v<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token keyword">to</span><span class="token punctuation">(</span><span class="token string">&quot;ks1Out&quot;</span><span class="token punctuation">,</span>
                <span class="token class-name">Produced</span><span class="token punctuation">.</span><span class="token keyword">with</span><span class="token punctuation">(</span><span class="token class-name">Serdes</span><span class="token punctuation">.</span><span class="token class-name">Integer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">JsonSerde</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token punctuation">&gt;</span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> stream<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x7531;&#x5176;&#x521B;&#x5EFA;&#x7684; <code>StreamBuilder</code> &#x5BF9;&#x8C61;&#x7BA1;&#x7406;&#x7684;&#x6D41;&#x4F1A;&#x81EA;&#x52A8;&#x542F;&#x52A8;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.kafka.streams.auto-startup</code> &#x5C5E;&#x6027;&#x81EA;&#x5B9A;&#x4E49;&#x6B64;&#x884C;&#x4E3A;&#x3002;</p>
<p><a id="boot-features-kafka-extra-props"></a></p>
<h3 id="3334&#x3001;&#x5176;&#x4ED6;-kafka-&#x5C5E;&#x6027;">33.3.4&#x3001;&#x5176;&#x4ED6; Kafka &#x5C5E;&#x6027;</h3>
<p>&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x652F;&#x6301;&#x7684;&#x5C5E;&#x6027;&#x53EF;&#x5728;<a href="#common-application-properties">&#x9644;&#x5F55; A&#x3001;&#x5E38;&#x89C1;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x5C5E;&#x6027;</a>&#x4E2D;&#x627E;&#x5230;&#x3002;&#x8BF7;&#x6CE8;&#x610F;&#xFF0C;&#x5728;&#x5927;&#x591A;&#x6570;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x8FD9;&#x4E9B;&#x5C5E;&#x6027;&#xFF08;&#x8FDE;&#x63A5;&#x7B26;&#x6216;&#x9A7C;&#x5CF0;&#x547D;&#x540D;&#xFF09;&#x76F4;&#x63A5;&#x6620;&#x5C04;&#x5230; Apache Kafka &#x70B9;&#x8FDE;&#x5F62;&#x5F0F;&#x5C5E;&#x6027;&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; Apache Kafka &#x6587;&#x6863;&#x3002;</p>
<p>&#x8FD9;&#x4E9B;&#x5C5E;&#x6027;&#x4E2D;&#x7684;&#x524D;&#x51E0;&#x4E2A;&#x9002;&#x7528;&#x4E8E;&#x6240;&#x6709;&#x7EC4;&#x4EF6;&#xFF08;&#x751F;&#x4EA7;&#x8005;&#x3010;producer&#x3011;&#x3001;&#x4F7F;&#x7528;&#x8005;&#x3010;consumer&#x3011;&#x3001;&#x7BA1;&#x7406;&#x8005;&#x3010;admin&#x3011;&#x548C;&#x6D41;&#x3010;stream&#x3011;&#xFF09;&#xFF0C;&#x4F46;&#x5982;&#x679C;&#x60A8;&#x5E0C;&#x671B;&#x4F7F;&#x7528;&#x4E0D;&#x540C;&#x7684;&#x503C;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5728;&#x7EC4;&#x4EF6;&#x7EA7;&#x522B;&#x6307;&#x5B9A;&#x3002;Apache Kafka &#x91CD;&#x8981;&#x6027;&#xFF08;&#x4F18;&#x5148;&#x7EA7;&#xFF09;&#x5C5E;&#x6027;&#x8BBE;&#x5B9A;&#x4E3A; HIGH&#x3001;MEDIUM &#x6216; LOW&#x3002;Spring Boot &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x652F;&#x6301;&#x6240;&#x6709; HIGH &#x91CD;&#x8981;&#x6027;&#x5C5E;&#x6027;&#xFF0C;&#x4E00;&#x4E9B;&#x9009;&#x62E9;&#x7684; MEDIUM &#x548C; LOW &#x5C5E;&#x6027;&#xFF0C;&#x4EE5;&#x53CA;&#x6240;&#x6709;&#x6CA1;&#x6709;&#x9ED8;&#x8BA4;&#x503C;&#x7684;&#x5C5E;&#x6027;&#x3002;</p>
<p>&#x53EA;&#x6709; Kafka &#x652F;&#x6301;&#x7684;&#x5C5E;&#x6027;&#x7684;&#x5B50;&#x96C6;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x901A;&#x8FC7; <code>KafkaProperties</code> &#x7C7B;&#x83B7;&#x5F97;&#x3002;&#x5982;&#x679C;&#x60A8;&#x5E0C;&#x671B;&#x4F7F;&#x7528;&#x4E0D;&#x53D7;&#x652F;&#x6301;&#x7684;&#x5176;&#x4ED6;&#x5C5E;&#x6027;&#x914D;&#x7F6E;&#x751F;&#x4EA7;&#x8005;&#x6216;&#x6D88;&#x8D39;&#x8005;&#xFF0C;&#x8BF7;&#x4F7F;&#x7528;&#x4EE5;&#x4E0B;&#x5C5E;&#x6027;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.kafka.properties.prop.one</span><span class="token attr-value"><span class="token punctuation">=</span>first</span>
<span class="token constant">spring.kafka.admin.properties.prop.two</span><span class="token attr-value"><span class="token punctuation">=</span>second</span>
<span class="token constant">spring.kafka.consumer.properties.prop.three</span><span class="token attr-value"><span class="token punctuation">=</span>third</span>
<span class="token constant">spring.kafka.producer.properties.prop.four</span><span class="token attr-value"><span class="token punctuation">=</span>fourth</span>
<span class="token constant">spring.kafka.streams.properties.prop.five</span><span class="token attr-value"><span class="token punctuation">=</span>fifth</span>
</code></pre>
<p>&#x8FD9;&#x5C06;&#x5E38;&#x89C1;&#x7684; <code>prop.one</code> Kafka &#x5C5E;&#x6027;&#x8BBE;&#x7F6E;&#x4E3A; <code>first</code>&#xFF08;&#x9002;&#x7528;&#x4E8E;&#x751F;&#x4EA7;&#x8005;&#x3001;&#x6D88;&#x8D39;&#x8005;&#x548C;&#x7BA1;&#x7406;&#x8005;&#xFF09;&#xFF0C;<code>prop.two</code> &#x7BA1;&#x7406;&#x8005;&#x5C5E;&#x6027;&#x4E3A; <code>second</code>&#xFF0C;<code>prop.three</code> &#x6D88;&#x8D39;&#x8005;&#x5C5E;&#x6027;&#x4E3A; <code>third</code>&#xFF0C;<code>prop.four</code> &#x751F;&#x4EA7;&#x8005;&#x5C5E;&#x6027;&#x4E3A; <code>fourth</code>&#xFF0C;<code>prop.five</code> &#x6D41;&#x5C5E;&#x6027;&#x4E3A; <code>fifth</code>&#x3002;</p>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x6309;&#x5982;&#x4E0B;&#x65B9;&#x5F0F;&#x914D;&#x7F6E; Spring Kafka <code>JsonDeserializer</code>&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.kafka.consumer.value-deserializer</span><span class="token attr-value"><span class="token punctuation">=</span>org.springframework.kafka.support.serializer.JsonDeserializer</span>
<span class="token constant">spring.kafka.consumer.properties.spring.json.value.default.type</span><span class="token attr-value"><span class="token punctuation">=</span>com.example.Invoice</span>
<span class="token constant">spring.kafka.consumer.properties.spring.json.trusted.packages</span><span class="token attr-value"><span class="token punctuation">=</span>com.example,org.acme</span>
</code></pre>
<p>&#x540C;&#x6837;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x7981;&#x7528; <code>JsonSerializer</code> &#x5728; header &#x4E2D;&#x53D1;&#x9001;&#x7C7B;&#x578B;&#x4FE1;&#x606F;&#x7684;&#x9ED8;&#x8BA4;&#x884C;&#x4E3A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.kafka.producer.value-serializer</span><span class="token attr-value"><span class="token punctuation">=</span>org.springframework.kafka.support.serializer.JsonSerializer</span>
<span class="token constant">spring.kafka.producer.properties.spring.json.add.type.headers</span><span class="token attr-value"><span class="token punctuation">=</span>false</span>
</code></pre>
<p><strong>&#x91CD;&#x8981;</strong></p>
<blockquote>
<p>&#x4EE5;&#x8FD9;&#x79CD;&#x65B9;&#x5F0F;&#x8BBE;&#x7F6E;&#x7684;&#x5C5E;&#x6027;&#x5C06;&#x8986;&#x76D6; Spring Boot &#x660E;&#x786E;&#x652F;&#x6301;&#x7684;&#x4EFB;&#x4F55;&#x914D;&#x7F6E;&#x9879;&#x3002;</p>
</blockquote>
<p><a id="boot-features-resttemplate"></a></p>
<h2 id="34&#x3001;&#x4F7F;&#x7528;-resttemplate-&#x8C03;&#x7528;-rest-&#x670D;&#x52A1;">34&#x3001;&#x4F7F;&#x7528; <code>RestTemplate</code> &#x8C03;&#x7528; REST &#x670D;&#x52A1;</h2>
<p>&#x5982;&#x679C;&#x60A8;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x9700;&#x8981;&#x8C03;&#x7528;&#x8FDC;&#x7A0B; REST &#x670D;&#x52A1;&#xFF0C;&#x8FD9;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; Spring Framework &#x7684; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/javadoc-api/org/springframework/web/client/RestTemplate.html" target="_blank"><code>RestTemplate</code></a> &#x7C7B;&#x3002;&#x7531;&#x4E8E; <code>RestTemplate</code> &#x5B9E;&#x4F8B;&#x5728;&#x4F7F;&#x7528;&#x4E4B;&#x524D;&#x901A;&#x5E38;&#x9700;&#x8981;&#x8FDB;&#x884C;&#x81EA;&#x5B9A;&#x4E49;&#xFF0C;&#x56E0;&#x6B64; Spring Boot &#x4E0D;&#x63D0;&#x4F9B;&#x4EFB;&#x4F55;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>RestTemplate</code> bean&#x3002;&#x4F46;&#x662F;&#xFF0C;&#x5B83;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E; <code>RestTemplateBuilder</code>&#xFF0C;&#x53EF;&#x5728;&#x9700;&#x8981;&#x65F6;&#x521B;&#x5EFA; <code>RestTemplate</code> &#x5B9E;&#x4F8B;&#x3002;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>RestTemplateBuilder</code> &#x786E;&#x4FDD;&#x5C06;&#x5408;&#x9002;&#x7684; <code>HttpMessageConverters</code> &#x5E94;&#x7528;&#x4E8E; <code>RestTemplate</code> &#x5B9E;&#x4F8B;&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#x5C55;&#x793A;&#x4E86;&#x4E00;&#x4E2A;&#x5178;&#x578B;&#x793A;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Service</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyService</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">RestTemplate</span> restTemplate<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">MyService</span><span class="token punctuation">(</span><span class="token class-name">RestTemplateBuilder</span> restTemplateBuilder<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>restTemplate <span class="token operator">=</span> restTemplateBuilder<span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">Details</span> <span class="token function">someRestCall</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>restTemplate<span class="token punctuation">.</span><span class="token function">getForObject</span><span class="token punctuation">(</span><span class="token string">&quot;/{name}/details&quot;</span><span class="token punctuation">,</span> <span class="token class-name">Details</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p><code>RestTemplateBuilder</code> &#x5305;&#x542B;&#x8BB8;&#x591A;&#x53EF;&#x7528;&#x4E8E;&#x5FEB;&#x901F;&#x914D;&#x7F6E; &#xB7;RestTemplate&#xB7; &#x7684;&#x65B9;&#x6CD5;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x8981;&#x6DFB;&#x52A0; BASIC auth &#x652F;&#x6301;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>builder.basicAuthentication(&quot;user&quot;, &quot;password&quot;).build()</code>&#x3002;</p>
</blockquote>
<p><a id="boot-features-resttemplate-customization"></a></p>
<h3 id="341&#x3001;&#x81EA;&#x5B9A;&#x4E49;-resttemplate">34.1&#x3001;&#x81EA;&#x5B9A;&#x4E49; RestTemplate</h3>
<p><code>RestTemplate</code> &#x81EA;&#x5B9A;&#x4E49;&#x6709;&#x4E09;&#x79CD;&#x4E3B;&#x8981;&#x65B9;&#x6CD5;&#xFF0C;&#x5177;&#x4F53;&#x53D6;&#x51B3;&#x4E8E;&#x60A8;&#x5E0C;&#x671B;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x7A0B;&#x5EA6;&#x3002;</p>
<p>&#x8981;&#x60F3;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x8303;&#x56F4;&#x5C3D;&#x53EF;&#x80FD;&#x5730;&#x7A84;&#xFF0C;&#x8BF7;&#x6CE8;&#x5165;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>RestTemplateBuilder</code>&#xFF0C;&#x7136;&#x540E;&#x6839;&#x636E;&#x9700;&#x8981;&#x8C03;&#x7528;&#x5176;&#x65B9;&#x6CD5;&#x3002;&#x6BCF;&#x4E2A;&#x65B9;&#x6CD5;&#x8C03;&#x7528;&#x90FD;&#x8FD4;&#x56DE;&#x4E00;&#x4E2A;&#x65B0;&#x7684; <code>RestTemplateBuilder</code> &#x5B9E;&#x4F8B;&#xFF0C;&#x56E0;&#x6B64;&#x81EA;&#x5B9A;&#x4E49;&#x53EA;&#x4F1A;&#x5F71;&#x54CD;&#x5F53;&#x524D;&#x6784;&#x5EFA;&#x5668;&#x3002;</p>
<p>&#x8981;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x8303;&#x56F4;&#x5185;&#x6DFB;&#x52A0;&#x81EA;&#x5B9A;&#x4E49;&#x914D;&#x7F6E;&#xFF0C;&#x8BF7;&#x4F7F;&#x7528; <code>RestTemplateCustomizer</code> bean&#x3002;&#x6240;&#x6709;&#x8FD9;&#x4E9B; bean &#x90FD;&#x4F1A;&#x81EA;&#x52A8;&#x6CE8;&#x518C;&#x5230;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>RestTemplateBuilder</code>&#xFF0C;&#x5E76;&#x5E94;&#x7528;&#x4E8E;&#x4F7F;&#x7528;&#x5B83;&#x6784;&#x5EFA;&#x7684;&#x6240;&#x6709;&#x6A21;&#x677F;&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x4E86;&#x4E00;&#x4E2A; customizer&#xFF0C;&#x5B83;&#x4E3A;&#x9664; <code>192.168.0.5</code> &#x4E4B;&#x5916;&#x7684;&#x6240;&#x6709;&#x4E3B;&#x673A;&#x914D;&#x7F6E;&#x4EE3;&#x7406;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">ProxyCustomizer</span> <span class="token keyword">implements</span> <span class="token class-name">RestTemplateCustomizer</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">customize</span><span class="token punctuation">(</span><span class="token class-name">RestTemplate</span> restTemplate<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token class-name">HttpHost</span> proxy <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">HttpHost</span><span class="token punctuation">(</span><span class="token string">&quot;proxy.example.com&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token class-name">HttpClient</span> httpClient <span class="token operator">=</span> <span class="token class-name">HttpClientBuilder</span><span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
                <span class="token punctuation">.</span><span class="token function">setRoutePlanner</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">DefaultProxyRoutePlanner</span><span class="token punctuation">(</span>proxy<span class="token punctuation">)</span> <span class="token punctuation">{</span>

                    <span class="token annotation punctuation">@Override</span>
                    <span class="token keyword">public</span> <span class="token class-name">HttpHost</span> <span class="token function">determineProxy</span><span class="token punctuation">(</span><span class="token class-name">HttpHost</span> target<span class="token punctuation">,</span>
                            <span class="token class-name">HttpRequest</span> request<span class="token punctuation">,</span> <span class="token class-name">HttpContext</span> context<span class="token punctuation">)</span>
                            <span class="token keyword">throws</span> <span class="token class-name">HttpException</span> <span class="token punctuation">{</span>
                        <span class="token keyword">if</span> <span class="token punctuation">(</span>target<span class="token punctuation">.</span><span class="token function">getHostName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span><span class="token string">&quot;192.168.0.5&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
                            <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
                        <span class="token punctuation">}</span>
                        <span class="token keyword">return</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">determineProxy</span><span class="token punctuation">(</span>target<span class="token punctuation">,</span> request<span class="token punctuation">,</span> context<span class="token punctuation">)</span><span class="token punctuation">;</span>
                    <span class="token punctuation">}</span>

                <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        restTemplate<span class="token punctuation">.</span><span class="token function">setRequestFactory</span><span class="token punctuation">(</span>
                <span class="token keyword">new</span> <span class="token class-name">HttpComponentsClientHttpRequestFactory</span><span class="token punctuation">(</span>httpClient<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x6700;&#x540E;&#xFF0C;&#x6700;&#x6781;&#x7AEF;&#xFF08;&#x4E5F;&#x5F88;&#x5C11;&#x4F7F;&#x7528;&#xFF09;&#x7684;&#x9009;&#x62E9;&#x662F;&#x521B;&#x5EFA;&#x81EA;&#x5DF1;&#x7684; <code>RestTemplateBuilder</code> bean&#x3002;&#x8FD9;&#x6837;&#x505A;&#x4F1A;&#x5173;&#x95ED; <code>RestTemplateBuilder</code> &#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x5E76;&#x963B;&#x6B62;&#x4F7F;&#x7528;&#x4EFB;&#x4F55; <code>RestTemplateCustomizer</code> bean&#x3002;</p>
<p><a id="boot-features-webclient"></a></p>
<h2 id="35&#x3001;&#x4F7F;&#x7528;-webclient-&#x8C03;&#x7528;-rest-&#x670D;&#x52A1;">35&#x3001;&#x4F7F;&#x7528; <code>WebClient</code> &#x8C03;&#x7528; REST &#x670D;&#x52A1;</h2>
<p>&#x5982;&#x679C;&#x5728; classpath &#x4E0A;&#x5B58;&#x5728; Spring WebFlux&#xFF0C;&#x5219;&#x8FD8;&#x53EF;&#x4EE5;&#x9009;&#x62E9;&#x4F7F;&#x7528; <code>WebClient</code> &#x6765;&#x8C03;&#x7528;&#x8FDC;&#x7A0B; REST &#x670D;&#x52A1;&#x3002;&#x4E0E; <code>RestTemplate</code> &#x76F8;&#x6BD4;&#xFF0C;&#x8BE5;&#x5BA2;&#x6237;&#x7AEF;&#x66F4;&#x5177;&#x51FD;&#x6570;&#x5F0F;&#x98CE;&#x683C;&#x5E76;&#x4E14;&#x5B8C;&#x5168;&#x54CD;&#x5E94;&#x5F0F;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x5728; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web-reactive.html#webflux-client" target="_blank">Spring Framework &#x6587;&#x6863;&#x7684;&#x76F8;&#x5173;&#x90E8;&#x5206;</a>&#x4E2D;&#x4E86;&#x89E3;&#x6709;&#x5173; <code>WebClient</code> &#x7684;&#x66F4;&#x591A;&#x4FE1;&#x606F;&#x3002;</p>
<p>Spring Boot &#x4E3A;&#x60A8;&#x521B;&#x5EFA;&#x5E76;&#x9884;&#x914D;&#x7F6E;&#x4E86;&#x4E00;&#x4E2A; <code>WebClient.Builder</code>&#x3002;&#x5F3A;&#x70C8;&#x5EFA;&#x8BAE;&#x5C06;&#x5176;&#x6CE8;&#x5165;&#x60A8;&#x7684;&#x7EC4;&#x4EF6;&#x4E2D;&#x5E76;&#x4F7F;&#x7528;&#x5B83;&#x6765;&#x521B;&#x5EFA; <code>WebClient</code> &#x5B9E;&#x4F8B;&#x3002;Spring Boot &#x914D;&#x7F6E;&#x8BE5;&#x6784;&#x5EFA;&#x5668;&#x4EE5;&#x5171;&#x4EAB; HTTP &#x8D44;&#x6E90;&#xFF0C;&#x4EE5;&#x4E0E;&#x670D;&#x52A1;&#x5668;&#x76F8;&#x540C;&#x7684;&#x65B9;&#x5F0F;&#x53CD;&#x5C04;&#x7F16;&#x89E3;&#x7801;&#x5668;&#x8BBE;&#x7F6E;&#xFF08;&#x8BF7;&#x53C2;&#x9605; <a href="#boot-features-webflux-httpcodecs">WebFlux HTTP &#x7F16;&#x89E3;&#x7801;&#x5668;&#x81EA;&#x52A8;&#x914D;&#x7F6E;</a>&#xFF09;&#x7B49;&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#x662F;&#x4E00;&#x4E2A;&#x5178;&#x578B;&#x793A;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Service</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyService</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">WebClient</span> webClient<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">MyService</span><span class="token punctuation">(</span><span class="token class-name">WebClient</span><span class="token punctuation">.</span><span class="token class-name">Builder</span> webClientBuilder<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>webClient <span class="token operator">=</span> webClientBuilder<span class="token punctuation">.</span><span class="token function">baseUrl</span><span class="token punctuation">(</span><span class="token string">&quot;http://example.org&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">Mono</span><span class="token generics"><span class="token punctuation">&lt;</span><span class="token class-name">Details</span><span class="token punctuation">&gt;</span></span> <span class="token function">someRestCall</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">.</span>webClient<span class="token punctuation">.</span><span class="token function">get</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">uri</span><span class="token punctuation">(</span><span class="token string">&quot;/{name}/details&quot;</span><span class="token punctuation">,</span> name<span class="token punctuation">)</span>
                        <span class="token punctuation">.</span><span class="token function">retrieve</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">bodyToMono</span><span class="token punctuation">(</span><span class="token class-name">Details</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-webclient-runtime"></a></p>
<h3 id="351&#x3001;webclient-&#x8FD0;&#x884C;&#x65F6;">35.1&#x3001;WebClient &#x8FD0;&#x884C;&#x65F6;</h3>
<p>Spring Boot &#x5C06;&#x81EA;&#x52A8;&#x68C0;&#x6D4B;&#x7528;&#x4E8E;&#x9A71;&#x52A8; <code>WebClient</code> &#x7684; <code>ClientHttpConnector</code>&#xFF0C;&#x5177;&#x4F53;&#x53D6;&#x51B3;&#x4E8E;&#x5E94;&#x7528;&#x7A0B;&#x5E8F; classpath &#x4E0A;&#x53EF;&#x7528;&#x7684;&#x7C7B;&#x5E93;&#x3002;&#x76EE;&#x524D;&#x652F;&#x6301; Reactor Netty &#x548C; Jetty RS &#x5BA2;&#x6237;&#x7AEF;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B; <code>spring-boot-starter-webflux</code> starter &#x4F9D;&#x8D56;&#x4E8E; <code>io.projectreactor.netty:reactor-netty</code>&#xFF0C;&#x5B83;&#x5305;&#x542B;&#x4E86;&#x670D;&#x52A1;&#x5668;&#x548C;&#x5BA2;&#x6237;&#x7AEF;&#x7684;&#x5B9E;&#x73B0;&#x3002;&#x5982;&#x679C;&#x60A8;&#x9009;&#x62E9;&#x5C06; <code>Jetty</code> &#x7528;&#x4F5C;&#x54CD;&#x5E94;&#x5F0F;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x5219;&#x5E94;&#x6DFB;&#x52A0; Jetty Reactive HTTP &#x5BA2;&#x6237;&#x7AEF;&#x5E93;&#x4F9D;&#x8D56;&#x9879; <code>org.eclipse.jetty:jetty-reactive-httpclient</code>&#x3002;&#x670D;&#x52A1;&#x5668;&#x548C;&#x5BA2;&#x6237;&#x7AEF;&#x4F7F;&#x7528;&#x76F8;&#x540C;&#x7684;&#x6280;&#x672F;&#x5177;&#x6709;&#x4E00;&#x5B9A;&#x4F18;&#x52BF;&#xFF0C;&#x56E0;&#x4E3A;&#x5B83;&#x4F1A;&#x81EA;&#x52A8;&#x5728;&#x5BA2;&#x6237;&#x7AEF;&#x548C;&#x670D;&#x52A1;&#x5668;&#x4E4B;&#x95F4;&#x5171;&#x4EAB; HTTP &#x8D44;&#x6E90;&#x3002;</p>
<p>&#x5F00;&#x53D1;&#x4EBA;&#x5458;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x63D0;&#x4F9B;&#x81EA;&#x5B9A;&#x4E49;&#x7684; <code>ReactorResourceFactory</code> &#x6216; <code>JettyResourceFactory</code> bean &#x6765;&#x8986;&#x76D6; Jetty &#x548C; Reactor Netty &#x7684;&#x8D44;&#x6E90;&#x914D;&#x7F6E; &#x2014;&#x2014; &#x8FD9;&#x5C06;&#x540C;&#x65F6;&#x5E94;&#x7528;&#x4E8E;&#x5BA2;&#x6237;&#x7AEF;&#x548C;&#x670D;&#x52A1;&#x5668;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x53EA;&#x5E0C;&#x671B;&#x8986;&#x76D6;&#x5BA2;&#x6237;&#x7AEF;&#x9009;&#x9879;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5B9A;&#x4E49;&#x81EA;&#x5DF1;&#x7684; <code>ClientHttpConnector</code> bean &#x5E76;&#x5B8C;&#x5168;&#x63A7;&#x5236;&#x5BA2;&#x6237;&#x7AEF;&#x914D;&#x7F6E;&#x3002;</p>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x5728; <a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/web-reactive.html#webflux-client-builder" target="_blank">Spring Framework &#x53C2;&#x8003;&#x6587;&#x6863;&#x4E2D;&#x4E86;&#x89E3;&#x6709;&#x5173; <code>WebClient</code> &#x914D;&#x7F6E;&#x9009;&#x9879;&#x7684;&#x66F4;&#x591A;&#x4FE1;&#x606F;</a>&#x3002;</p>
<p><a id="boot-features-webclient-customization"></a></p>
<h3 id="352&#x3001;&#x81EA;&#x5B9A;&#x4E49;-webclient">35.2&#x3001;&#x81EA;&#x5B9A;&#x4E49; WebClient</h3>
<p><code>WebClient</code> &#x81EA;&#x5B9A;&#x4E49;&#x6709;&#x4E09;&#x79CD;&#x4E3B;&#x8981;&#x65B9;&#x6CD5;&#xFF0C;&#x5177;&#x4F53;&#x53D6;&#x51B3;&#x4E8E;&#x60A8;&#x5E0C;&#x671B;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x7A0B;&#x5EA6;&#x3002;</p>
<p>&#x8981;&#x60F3;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x8303;&#x56F4;&#x5C3D;&#x53EF;&#x80FD;&#x5730;&#x7A84;&#xFF0C;&#x8BF7;&#x6CE8;&#x5165;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>WebClient.Builder</code>&#xFF0C;&#x7136;&#x540E;&#x6839;&#x636E;&#x9700;&#x8981;&#x8C03;&#x7528;&#x5176;&#x65B9;&#x6CD5;&#x3002;<code>WebClient.Builder</code> &#x5B9E;&#x4F8B;&#x662F;&#x6709;&#x72B6;&#x6001;&#x7684;&#xFF1A;&#x6784;&#x5EFA;&#x5668;&#x4E0A;&#x7684;&#x4EFB;&#x4F55;&#x66F4;&#x6539;&#x90FD;&#x4F1A;&#x5F71;&#x54CD;&#x5230;&#x4E4B;&#x540E;&#x6240;&#x6709;&#x4F7F;&#x7528;&#x5B83;&#x521B;&#x5EFA;&#x7684;&#x5BA2;&#x6237;&#x7AEF;&#x3002;&#x5982;&#x679C;&#x8981;&#x4F7F;&#x7528;&#x76F8;&#x540C;&#x7684;&#x6784;&#x5EFA;&#x5668;&#x521B;&#x5EFA;&#x591A;&#x4E2A;&#x5BA2;&#x6237;&#x7AEF;&#xFF0C;&#x53EF;&#x4EE5;&#x8003;&#x8651;&#x4F7F;&#x7528; <code>WebClient.Builder other = builder.clone();</code> &#x7684;&#x65B9;&#x5F0F;&#x514B;&#x9686;&#x6784;&#x5EFA;&#x5668;&#x3002;</p>
<p>&#x8981;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x8303;&#x56F4;&#x5185;&#x5BF9;&#x6240;&#x6709; <code>WebClient.Builder</code> &#x5B9E;&#x4F8B;&#x6DFB;&#x52A0;&#x81EA;&#x5B9A;&#x4E49;&#xFF0C;&#x53EF;&#x4EE5;&#x58F0;&#x660E; <code>WebClientCustomizer</code> bean &#x5E76;&#x5728;&#x6CE8;&#x5165;&#x70B9;&#x5C40;&#x90E8;&#x66F4;&#x6539; <code>WebClient.Builder</code>&#x3002;</p>
<p>&#x6700;&#x540E;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x56DE;&#x9000;&#x5230;&#x539F;&#x59CB; API &#x5E76;&#x4F7F;&#x7528; <code>WebClient.create()</code>&#x3002;&#x5728;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x4E0D;&#x4F1A;&#x5E94;&#x7528;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x6216; <code>WebClientCustomizer</code>&#x3002;</p>
<p><a id="boot-features-validation"></a></p>
<h2 id="36&#x3001;&#x9A8C;&#x8BC1;">36&#x3001;&#x9A8C;&#x8BC1;</h2>
<p>&#x53EA;&#x8981; classpath &#x4E0A;&#x5B58;&#x5728; JSR-303 &#x5B9E;&#x73B0;&#xFF08;&#x4F8B;&#x5982; Hibernate &#x9A8C;&#x8BC1;&#x5668;&#xFF09;&#xFF0C;&#x5C31;&#x4F1A;&#x81EA;&#x52A8;&#x542F;&#x7528; Bean Validation 1.1 &#x652F;&#x6301;&#x7684;&#x65B9;&#x6CD5;&#x9A8C;&#x8BC1;&#x529F;&#x80FD;&#x3002;&#x8FD9;&#x5141;&#x8BB8; bean &#x65B9;&#x6CD5;&#x5728;&#x5176;&#x53C2;&#x6570;&#x548C;/&#x6216;&#x8FD4;&#x56DE;&#x503C;&#x4E0A;&#x4F7F;&#x7528; <code>javax.validation</code> &#x7EA6;&#x675F;&#x8FDB;&#x884C;&#x6CE8;&#x89E3;&#x3002;&#x5E26;&#x6709;&#x6B64;&#x7C7B;&#x6CE8;&#x89E3;&#x65B9;&#x6CD5;&#x7684;&#x76EE;&#x6807;&#x7C7B;&#x9700;&#x8981;&#x5728;&#x7C7B;&#x7EA7;&#x522B;&#x4E0A;&#x4F7F;&#x7528; <code>@Validated</code> &#x8FDB;&#x884C;&#x6CE8;&#x89E3;&#xFF0C;&#x4EE5;&#x4FBF;&#x641C;&#x7D22;&#x5176;&#x5185;&#x8054;&#x7EA6;&#x675F;&#x6CE8;&#x89E3;&#x7684;&#x65B9;&#x6CD5;&#x3002;</p>
<p>&#x4F8B;&#x5982;&#xFF0C;&#x4EE5;&#x4E0B;&#x670D;&#x52A1;&#x89E6;&#x53D1;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x7684;&#x9A8C;&#x8BC1;&#xFF0C;&#x786E;&#x4FDD;&#x5176;&#x5927;&#x5C0F;&#x5728; 8 &#x5230; 10 &#x4E4B;&#x95F4;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Service</span>
<span class="token annotation punctuation">@Validated</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">public</span> <span class="token class-name">Archive</span> <span class="token function">findByCodeAndAuthor</span><span class="token punctuation">(</span><span class="token annotation punctuation">@Size</span><span class="token punctuation">(</span>min <span class="token operator">=</span> <span class="token number">8</span><span class="token punctuation">,</span> max <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token class-name">String</span> code<span class="token punctuation">,</span>
            <span class="token class-name">Author</span> author<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-email"></a></p>
<h2 id="37&#x3001;&#x53D1;&#x9001;&#x90AE;&#x4EF6;">37&#x3001;&#x53D1;&#x9001;&#x90AE;&#x4EF6;</h2>
<p>Spring Framework &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x4F7F;&#x7528; <code>JavaMailSender</code> &#x63A5;&#x53E3;&#x53D1;&#x9001;&#x7535;&#x5B50;&#x90AE;&#x4EF6;&#x7684;&#x7B80;&#x5355;&#x62BD;&#x8C61;&#xFF0C;Spring Boot &#x4E3A;&#x5176;&#x63D0;&#x4F9B;&#x4E86;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4EE5;&#x53CA;&#x4E00;&#x4E2A; starter &#x6A21;&#x5757;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x6709;&#x5173;&#x5982;&#x4F55;&#x4F7F;&#x7528; <code>JavaMailSender</code> &#x7684;&#x8BE6;&#x7EC6;&#x8BF4;&#x660E;&#xFF0C;&#x8BF7;&#x53C2;&#x9605;<a href="https://docs.spring.io/spring/docs/5.1.3.RELEASE/spring-framework-reference/integration.html#mail" target="_blank">&#x53C2;&#x8003;&#x6587;&#x6863;</a>&#x3002;</p>
</blockquote>
<p>&#x5982;&#x679C; <code>spring.mail.host</code> &#x548C;&#x76F8;&#x5173;&#x5E93;&#xFF08;&#x7531; <code>spring-boot-starter-mail</code> &#x5B9A;&#x4E49;&#xFF09;&#x53EF;&#x7528;&#xFF0C;&#x5219;&#x521B;&#x5EFA;&#x9ED8;&#x8BA4;&#x7684; <code>JavaMailSender</code>&#xFF08;&#x5982;&#x679C;&#x4E0D;&#x5B58;&#x5728;&#xFF09;&#x3002;&#x53EF;&#x4EE5;&#x901A;&#x8FC7; <code>spring.mail</code> &#x547D;&#x540D;&#x7A7A;&#x95F4;&#x4E2D;&#x7684;&#x914D;&#x7F6E;&#x9879;&#x8FDB;&#x4E00;&#x6B65;&#x81EA;&#x5B9A;&#x4E49;&#x53D1;&#x4EF6;&#x4EBA;&#x3002;&#x6709;&#x5173;&#x66F4;&#x591A;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mail/MailProperties.java" target="_blank"><code>MailProperties</code></a>&#x3002;</p>
<p>&#x7279;&#x522B;&#x662F;&#xFF0C;&#x67D0;&#x4E9B;&#x9ED8;&#x8BA4;&#x8D85;&#x65F6;&#x65F6;&#x95F4;&#x7684;&#x503C;&#x662F;&#x65E0;&#x9650;&#x7684;&#xFF0C;&#x60A8;&#x53EF;&#x80FD;&#x60F3;&#x66F4;&#x6539;&#x5B83;&#x4EE5;&#x907F;&#x514D;&#x7EBF;&#x7A0B;&#x88AB;&#x65E0;&#x54CD;&#x5E94;&#x7684;&#x90AE;&#x4EF6;&#x670D;&#x52A1;&#x5668;&#x963B;&#x585E;&#xFF0C;&#x5982;&#x4E0B;&#x793A;&#x4F8B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.mail.properties.mail.smtp.connectiontimeout</span><span class="token attr-value"><span class="token punctuation">=</span>5000</span>
<span class="token constant">spring.mail.properties.mail.smtp.timeout</span><span class="token attr-value"><span class="token punctuation">=</span>3000</span>
<span class="token constant">spring.mail.properties.mail.smtp.writetimeout</span><span class="token attr-value"><span class="token punctuation">=</span>5000</span>
</code></pre>
<p>&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; JNDI &#x4E2D;&#x7684;&#x73B0;&#x6709; <code>Session</code> &#x914D;&#x7F6E;&#x4E00;&#x4E2A; <code>JavaMailSender</code>&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.mail.jndi-name</span><span class="token attr-value"><span class="token punctuation">=</span>mail/Session</span>
</code></pre>
<p>&#x8BBE;&#x7F6E; <code>jndi-name</code> &#x65F6;&#xFF0C;&#x5B83;&#x4F18;&#x5148;&#x4E8E;&#x6240;&#x6709;&#x5176;&#x4ED6;&#x4E0E; <code>Session</code> &#x76F8;&#x5173;&#x7684;&#x8BBE;&#x7F6E;&#x3002;</p>
<p><a id="boot-features-jta"></a></p>
<h2 id="38&#x3001;jta-&#x5206;&#x5E03;&#x5F0F;&#x4E8B;&#x52A1;">38&#x3001;JTA &#x5206;&#x5E03;&#x5F0F;&#x4E8B;&#x52A1;</h2>
<p>Spring Boot &#x901A;&#x8FC7;&#x4F7F;&#x7528; <a href="http://www.atomikos.com/" target="_blank">Atomikos</a> &#x6216; <a href="https://github.com/bitronix/btm" target="_blank">Bitronix</a> &#x5D4C;&#x5165;&#x5F0F;&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;&#x6765;&#x652F;&#x6301;&#x8DE8;&#x591A;&#x4E2A; XA &#x8D44;&#x6E90;&#x7684;&#x5206;&#x5E03;&#x5F0F; JTA &#x4E8B;&#x52A1;&#x3002;&#x90E8;&#x7F72;&#x5728;&#x67D0;&#x4E9B; Java EE &#x5E94;&#x7528;&#x670D;&#x52A1;&#x5668;&#xFF08;Application Server&#xFF09;&#x4E0A;&#x4E5F;&#x652F;&#x6301; JTA &#x4E8B;&#x52A1;&#x3002;</p>
<p>&#x5F53;&#x68C0;&#x6D4B;&#x5230; JTA &#x73AF;&#x5883;&#x65F6;&#xFF0C;Spring &#x7684; <code>JtaTransactionManager</code> &#x5C06;&#x7528;&#x4E8E;&#x7BA1;&#x7406;&#x4E8B;&#x52A1;&#x3002;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; JMS&#x3001;DataSource &#x548C; JPA bean &#x5DF2;&#x5347;&#x7EA7;&#x4E3A;&#x652F;&#x6301; XA &#x4E8B;&#x52A1;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x6807;&#x51C6;&#x7684; Spring &#x65B9;&#x5F0F;&#xFF08;&#x4F8B;&#x5982; <code>@Transactional</code>&#xFF09;&#x6765;&#x4F7F;&#x7528;&#x5206;&#x5E03;&#x5F0F;&#x4E8B;&#x52A1;&#x3002;&#x5982;&#x679C;&#x60A8;&#x5904;&#x4E8E; JTA &#x73AF;&#x5883;&#x4E2D;&#x5E76;&#x4E14;&#x4ECD;&#x60F3;&#x4F7F;&#x7528;&#x672C;&#x5730;&#x4E8B;&#x52A1;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5C06; <code>spring.jta.enabled</code> &#x5C5E;&#x6027;&#x8BBE;&#x7F6E;&#x4E3A; <code>false</code> &#x4EE5;&#x7981;&#x7528; JTA &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;</p>
<p><a id="boot-features-jta-atomikos"></a></p>
<h3 id="381&#x3001;&#x4F7F;&#x7528;-atomikos-&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;">38.1&#x3001;&#x4F7F;&#x7528; Atomikos &#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;</h3>
<p><a href="https://www.atomikos.com/" target="_blank">Atomikos</a> &#x662F;&#x4E00;&#x4E2A;&#x6D41;&#x884C;&#x7684;&#x5F00;&#x6E90;&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;&#xFF0C;&#x53EF;&#x4EE5;&#x5D4C;&#x5165;&#x5230; Spring Boot &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring-boot-starter-jta-atomikos</code> starter &#x6765;&#x83B7;&#x53D6;&#x76F8;&#x5E94;&#x7684; Atomikos &#x5E93;&#x3002;Spring Boot &#x81EA;&#x52A8;&#x914D;&#x7F6E; Atomikos &#x5E76;&#x786E;&#x4FDD;&#x5C06;&#x5408;&#x9002;&#x7684;&#x4F9D;&#x8D56;&#x8BBE;&#x7F6E;&#x5E94;&#x7528;&#x4E8E; Spring bean&#xFF0C;&#x4EE5;&#x786E;&#x4FDD;&#x542F;&#x52A8;&#x548C;&#x5173;&#x95ED;&#x987A;&#x5E8F;&#x6B63;&#x786E;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Atomikos &#x4E8B;&#x52A1;&#x65E5;&#x5FD7;&#x5C06;&#x5199;&#x5165;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E3B;&#x76EE;&#x5F55;&#xFF08;&#x5E94;&#x7528;&#x7A0B;&#x5E8F; jar &#x6587;&#x4EF6;&#x6240;&#x5728;&#x7684;&#x76EE;&#x5F55;&#xFF09;&#x4E2D;&#x7684; <code>transaction-logs</code> &#x76EE;&#x5F55;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x5728; <code>application.properties</code> &#x6587;&#x4EF6;&#x4E2D;&#x8BBE;&#x7F6E; <code>spring.jta.log-dir</code> &#x5C5E;&#x6027;&#x6765;&#x81EA;&#x5B9A;&#x4E49;&#x6B64;&#x76EE;&#x5F55;&#x7684;&#x4F4D;&#x7F6E;&#x3002;&#x4E5F;&#x53EF;&#x7528; <code>spring.jta.atomikos.properties</code> &#x5F00;&#x5934;&#x7684;&#x5C5E;&#x6027;&#x6765;&#x81EA;&#x5B9A;&#x4E49; Atomikos <code>UserTransactionServiceImp</code>&#x3002;&#x6709;&#x5173;&#x5B8C;&#x6574;&#x7684;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://docs.spring.io/spring-boot/docs/2.1.1.RELEASE/api/org/springframework/boot/jta/atomikos/AtomikosProperties.html" target="_blank">AtomikosProperties Javadoc</a>&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x4E3A;&#x786E;&#x4FDD;&#x591A;&#x4E2A;&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;&#x53EF;&#x4EE5;&#x5B89;&#x5168;&#x5730;&#x534F;&#x8C03;&#x76F8;&#x540C;&#x7684;&#x8D44;&#x6E90;&#x7BA1;&#x7406;&#x5668;&#xFF0C;&#x5FC5;&#x987B;&#x4E3A;&#x6BCF;&#x4E2A; Atomikos &#x5B9E;&#x4F8B;&#x914D;&#x7F6E;&#x552F;&#x4E00; ID&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x6B64; ID &#x662F;&#x8FD0;&#x884C; Atomikos &#x7684;&#x8BA1;&#x7B97;&#x673A;&#x7684; IP &#x5730;&#x5740;&#x3002;&#x5728;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x4E2D;&#x8981;&#x786E;&#x4FDD;&#x552F;&#x4E00;&#x6027;&#xFF0C;&#x5E94;&#x4E3A;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x6BCF;&#x4E2A;&#x5B9E;&#x4F8B;&#x914D;&#x7F6E; <code>spring.jta.transaction-manager-id</code> &#x5C5E;&#x6027;&#xFF0C;&#x5E76;&#x4F7F;&#x7528;&#x4E0D;&#x540C;&#x7684;&#x503C;&#x3002;</p>
</blockquote>
<p><a id="boot-features-jta-bitronix"></a></p>
<h3 id="382&#x3001;&#x4F7F;&#x7528;-bitronix-&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;">38.2&#x3001;&#x4F7F;&#x7528; Bitronix &#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;</h3>
<p><a href="https://github.com/bitronix/btm" target="_blank">Bitronix</a> &#x662F;&#x4E00;&#x4E2A;&#x6D41;&#x884C;&#x7684;&#x5F00;&#x6E90; JTA &#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;&#x5B9E;&#x73B0;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring-boot-starter-jta-bitronix</code> starter &#x4E3A;&#x60A8;&#x7684;&#x9879;&#x76EE;&#x6DFB;&#x52A0;&#x5408;&#x9002;&#x7684; Bitronix &#x4F9D;&#x8D56;&#x3002;&#x4E0E; Atomikos &#x4E00;&#x6837;&#xFF0C;Spring Boot &#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E; Bitronix &#x5E76;&#x5BF9; bean &#x8FDB;&#x884C;&#x540E;&#x5904;&#x7406;&#xFF08;post-processes&#xFF09;&#xFF0C;&#x4EE5;&#x786E;&#x4FDD;&#x542F;&#x52A8;&#x548C;&#x5173;&#x95ED;&#x987A;&#x5E8F;&#x6B63;&#x786E;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Bitronix &#x4E8B;&#x52A1;&#x65E5;&#x5FD7;&#x6587;&#x4EF6;&#xFF08;<code>part1.btm</code> &#x548C; <code>part2.btm</code>&#xFF09;&#x5C06;&#x5199;&#x5165;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E3B;&#x76EE;&#x5F55;&#x4E2D;&#x7684; <code>transaction-logs</code> &#x76EE;&#x5F55;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>spring.jta.log-dir</code> &#x5C5E;&#x6027;&#x6765;&#x81EA;&#x5B9A;&#x4E49;&#x6B64;&#x76EE;&#x5F55;&#x7684;&#x4F4D;&#x7F6E;&#x3002;&#x4EE5; <code>spring.jta.bitronix.properties</code> &#x5F00;&#x5934;&#x7684;&#x5C5E;&#x6027;&#x7ED1;&#x5B9A;&#x5230;&#x4E86; <code>bitronix.tm.Configuration</code> bean&#xFF0C;&#x5141;&#x8BB8;&#x5B8C;&#x5168;&#x81EA;&#x5B9A;&#x4E49;&#x3002;&#x6709;&#x5173;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/bitronix/btm/wiki/Transaction-manager-configuration" target="_blank">Bitronix &#x6587;&#x6863;</a>&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x4E3A;&#x786E;&#x4FDD;&#x591A;&#x4E2A;&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;&#x80FD;&#x591F;&#x5B89;&#x5168;&#x5730;&#x534F;&#x8C03;&#x76F8;&#x540C;&#x7684;&#x8D44;&#x6E90;&#x7BA1;&#x7406;&#x5668;&#xFF0C;&#x5FC5;&#x987B;&#x4E3A;&#x6BCF;&#x4E2A; Bitronix &#x5B9E;&#x4F8B;&#x914D;&#x7F6E;&#x552F;&#x4E00;&#x7684; ID&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x6B64; ID &#x662F;&#x8FD0;&#x884C; Bitronix &#x7684;&#x8BA1;&#x7B97;&#x673A;&#x7684; IP &#x5730;&#x5740;&#x3002;&#x751F;&#x4EA7;&#x73AF;&#x5883;&#x8981;&#x786E;&#x4FDD;&#x552F;&#x4E00;&#x6027;&#xFF0C;&#x5E94;&#x4E3A;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x6BCF;&#x4E2A;&#x5B9E;&#x4F8B;&#x914D;&#x7F6E; <code>spring.jta.transaction-manager-id</code> &#x5C5E;&#x6027;&#xFF0C;&#x5E76;&#x4F7F;&#x7528;&#x4E0D;&#x540C;&#x7684;&#x503C;&#x3002;</p>
</blockquote>
<p><a id="boot-features-jta-javaee"></a></p>
<h3 id="383&#x3001;&#x4F7F;&#x7528;-java-ee-&#x7BA1;&#x7406;&#x7684;&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;">38.3&#x3001;&#x4F7F;&#x7528; Java EE &#x7BA1;&#x7406;&#x7684;&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;</h3>
<p>&#x5982;&#x679C;&#x5C06; Spring Boot &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x6253;&#x5305;&#x4E3A; <code>war</code> &#x6216; <code>ear</code> &#x6587;&#x4EF6;&#x5E76;&#x5C06;&#x5176;&#x90E8;&#x7F72;&#x5230; Java EE &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x670D;&#x52A1;&#x5668;&#x7684;&#x5185;&#x7F6E;&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;&#x3002;Spring Boot &#x5C1D;&#x8BD5;&#x901A;&#x8FC7;&#x67E5;&#x627E;&#x5E38;&#x89C1;&#x7684; JNDI &#x4F4D;&#x7F6E;&#xFF08;<code>java:comp/UserTransaction</code>&#x3001;<code>java:comp/TransactionManager</code> &#x7B49;&#xFF09;&#x6765;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;&#x3002;&#x5982;&#x679C;&#x4F7F;&#x7528;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x670D;&#x52A1;&#x5668;&#x63D0;&#x4F9B;&#x7684;&#x4E8B;&#x52A1;&#x670D;&#x52A1;&#xFF0C;&#x901A;&#x5E38;&#x8FD8;&#x9700;&#x8981;&#x786E;&#x4FDD;&#x6240;&#x6709;&#x8D44;&#x6E90;&#x90FD;&#x7531;&#x670D;&#x52A1;&#x5668;&#x7BA1;&#x7406;&#x5E76;&#x901A;&#x8FC7; JNDI &#x66B4;&#x9732;&#x3002;Spring Boot &#x5C1D;&#x8BD5;&#x901A;&#x8FC7;&#x5728; JNDI &#x8DEF;&#x5F84;&#xFF08;<code>java:/JmsXA</code> &#x6216; <code>java:/JmsXA</code>&#xFF09;&#x4E2D;&#x67E5;&#x627E; <code>ConnectionFactory</code> &#x6765;&#x81EA;&#x52A8;&#x914D;&#x7F6E; JMS&#xFF0C;&#x5E76;&#x4E14;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <a href="#boot-features-connecting-to-a-jndi-datasource"><code>spring.datasource.jndi-name</code> &#x5C5E;&#x6027;</a>&#x6765;&#x914D;&#x7F6E; <code>DataSource</code>&#x3002;</p>
<p><a id="boot-features-jta-mixed-jms"></a></p>
<h3 id="384&#x3001;&#x6DF7;&#x5408;&#x4F7F;&#x7528;-xa-&#x4E0E;&#x975E;-xa-jms-&#x8FDE;&#x63A5;">38.4&#x3001;&#x6DF7;&#x5408;&#x4F7F;&#x7528; XA &#x4E0E;&#x975E; XA JMS &#x8FDE;&#x63A5;</h3>
<p>&#x4F7F;&#x7528; JTA &#x65F6;&#xFF0C;&#x4E3B; JMS <code>ConnectionFactory</code> bean &#x53EF;&#x8BC6;&#x522B; XA &#x5E76;&#x53C2;&#x4E0E;&#x5206;&#x5E03;&#x5F0F;&#x4E8B;&#x52A1;&#x3002;&#x5728;&#x67D0;&#x4E9B;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x60A8;&#x53EF;&#x80FD;&#x5E0C;&#x671B;&#x4F7F;&#x7528;&#x975E; XA <code>ConnectionFactory</code> &#x5904;&#x7406;&#x67D0;&#x4E9B; JMS &#x6D88;&#x606F;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x60A8;&#x7684; JMS &#x5904;&#x7406;&#x903B;&#x8F91;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x6BD4; XA &#x8D85;&#x65F6;&#x65F6;&#x95F4;&#x66F4;&#x957F;&#x7684;&#x65F6;&#x95F4;&#x3002;</p>
<p>&#x5982;&#x679C;&#x8981;&#x4F7F;&#x7528;&#x975E; XA <code>ConnectionFactory</code>&#xFF0C;&#x53EF;&#x4EE5;&#x6CE8;&#x5165; <code>nonXaJmsConnectionFactory</code> bean &#x800C;&#x4E0D;&#x662F; <code>@Primary</code> <code>jmsConnectionFactory</code> bean&#x3002;&#x4E3A;&#x4E86;&#x4FDD;&#x6301;&#x4E00;&#x81F4;&#x6027;&#xFF0C;&#x63D0;&#x4F9B;&#x7684; <code>jmsConnectionFactory</code> bean &#x8FD8;&#x9700;&#x8981;&#x4F7F;&#x7528; <code>xaJmsConnectionFactory</code> &#x522B;&#x540D;&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x6CE8;&#x5165; <code>ConnectionFactory</code> &#x5B9E;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token comment">// Inject the primary (XA aware) ConnectionFactory</span>
<span class="token annotation punctuation">@Autowired</span>
<span class="token keyword">private</span> <span class="token class-name">ConnectionFactory</span> defaultConnectionFactory<span class="token punctuation">;</span>

<span class="token comment">// Inject the XA aware ConnectionFactory (uses the alias and injects the same as above)</span>
<span class="token annotation punctuation">@Autowired</span>
<span class="token annotation punctuation">@Qualifier</span><span class="token punctuation">(</span><span class="token string">&quot;xaJmsConnectionFactory&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">private</span> <span class="token class-name">ConnectionFactory</span> xaConnectionFactory<span class="token punctuation">;</span>

<span class="token comment">// Inject the non-XA aware ConnectionFactory</span>
<span class="token annotation punctuation">@Autowired</span>
<span class="token annotation punctuation">@Qualifier</span><span class="token punctuation">(</span><span class="token string">&quot;nonXaJmsConnectionFactory&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">private</span> <span class="token class-name">ConnectionFactory</span> nonXaConnectionFactory<span class="token punctuation">;</span>
</code></pre>
<p><a id="boot-features-jta-supporting-alternative-embedded"></a></p>
<h3 id="385&#x3001;&#x652F;&#x6301;&#x5D4C;&#x5165;&#x5F0F;&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;">38.5&#x3001;&#x652F;&#x6301;&#x5D4C;&#x5165;&#x5F0F;&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;</h3>
<p><a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jms/XAConnectionFactoryWrapper.java" target="_blank"><code>XAConnectionFactoryWrapper</code></a> &#x548C; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jdbc/XADataSourceWrapper.java" target="_blank"><code>XADataSourceWrapper</code></a> &#x63A5;&#x53E3;&#x53EF;&#x7528;&#x4E8E;&#x652F;&#x6301;&#x5176;&#x4ED6;&#x5D4C;&#x5165;&#x5F0F;&#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;&#x3002;&#x63A5;&#x53E3;&#x8D1F;&#x8D23;&#x5305;&#x88C5; <code>XAConnectionFactory</code> &#x548C; <code>XADataSource</code> bean&#xFF0C;&#x5E76;&#x5C06;&#x5B83;&#x4EEC;&#x516C;&#x5F00;&#x4E3A;&#x666E;&#x901A;&#x7684; <code>ConnectionFactory</code> &#x548C; <code>DataSource</code> bean&#xFF0C;&#x5B83;&#x4EEC;&#x900F;&#x660E;&#x5730;&#x52A0;&#x5165;&#x5206;&#x5E03;&#x5F0F;&#x4E8B;&#x52A1;&#x3002;<code>DataSource</code> &#x548C; JMS &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4F7F;&#x7528; JTA &#x53D8;&#x4F53;&#xFF0C;&#x524D;&#x63D0;&#x662F;&#x60A8;&#x9700;&#x8981;&#x6709;&#x4E00;&#x4E2A; <code>JtaTransactionManager</code> bean &#x548C;&#x5728; <code>ApplicationContext</code> &#x4E2D;&#x6CE8;&#x518C;&#x6709;&#x7684;&#x76F8;&#x5E94; XA &#x5305;&#x88C5;&#x5668;&#xFF08;wrapper&#xFF09; bean&#x3002;</p>
<p><a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/BitronixXAConnectionFactoryWrapper.java" target="_blank">BitronixXAConnectionFactoryWrapper</a> &#x548C; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.1.RELEASE/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/jta/bitronix/BitronixXADataSourceWrapper.java" target="_blank">BitronixXADataSourceWrapper</a> &#x4E3A;&#x5982;&#x4F55;&#x7F16;&#x5199; XA &#x5305;&#x88C5;&#x5668;&#x63D0;&#x4F9B;&#x4E86;&#x5F88;&#x597D;&#x793A;&#x4F8B;&#x3002;</p>
<p><a id="boot-features-hazelcast"></a></p>
<h2 id="39&#x3001;hazelcast">39&#x3001;Hazelcast</h2>
<p>&#x5982;&#x679C; <a href="https://hazelcast.com/" target="_blank">Hazelcast</a> &#x5728; classpath &#x4E0A;&#x5E76;&#x6709;&#x5408;&#x9002;&#x7684;&#x914D;&#x7F6E;&#xFF0C;&#x5219; Spring Boot &#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A;&#x53EF;&#x4EE5;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x6CE8;&#x5165;&#x7684; <code>HazelcastInstance</code>&#x3002;</p>
<p>&#x5982;&#x679C;&#x5B9A;&#x4E49;&#x4E86; <code>com.hazelcast.config.Config</code> bean&#xFF0C;&#x5219; Spring Boot &#x4F1A;&#x4F7F;&#x7528;&#x5B83;&#x3002;&#x5982;&#x679C;&#x60A8;&#x7684;&#x914D;&#x7F6E;&#x5B9A;&#x4E49;&#x4E86;&#x5B9E;&#x4F8B;&#x540D;&#x79F0;&#xFF0C;Spring Boot &#x4F1A;&#x5C1D;&#x8BD5;&#x67E5;&#x627E;&#x73B0;&#x6709;&#x7684;&#x5B9E;&#x4F8B;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x521B;&#x5EFA;&#x65B0;&#x5B9E;&#x4F8B;&#x3002;</p>
<p>&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x914D;&#x7F6E;&#x6307;&#x5B9A;&#x8981;&#x4F7F;&#x7528;&#x7684; <code>hazelcast.xml</code> &#x914D;&#x7F6E;&#x6587;&#x4EF6;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.hazelcast.config</span><span class="token attr-value"><span class="token punctuation">=</span>classpath:config/my-hazelcast.xml</span>
</code></pre>
<p>&#x5426;&#x5219;&#xFF0C;Spring Boot &#x4F1A;&#x5C1D;&#x8BD5;&#x4ECE;&#x9ED8;&#x8BA4;&#x4F4D;&#x7F6E;&#x67E5;&#x627E; Hazelcast &#x914D;&#x7F6E;&#xFF1A;&#x5DE5;&#x4F5C;&#x76EE;&#x5F55;&#x6216; classpath &#x6839;&#x76EE;&#x5F55;&#x4E2D;&#x7684; <code>hazelcast.xml</code> &#x3002;&#x6211;&#x4EEC;&#x8FD8;&#x68C0;&#x67E5;&#x662F;&#x5426;&#x8BBE;&#x7F6E;&#x4E86; <code>hazelcast.config</code> &#x7CFB;&#x7EDF;&#x5C5E;&#x6027;&#x3002;&#x6709;&#x5173;&#x66F4;&#x591A;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="http://docs.hazelcast.org/docs/latest/manual/html-single/" target="_blank">Hazelcast &#x6587;&#x6863;</a>&#x3002;</p>
<p>&#x5982;&#x679C; classpath &#x4E2D;&#x5B58;&#x5728; <code>hazelcast-client</code>&#xFF0C;&#x5219; Spring Boot &#x4F1A;&#x9996;&#x5148;&#x5C1D;&#x8BD5;&#x901A;&#x8FC7;&#x68C0;&#x67E5;&#x4EE5;&#x4E0B;&#x914D;&#x7F6E;&#x9879;&#x6765;&#x521B;&#x5EFA;&#x5BA2;&#x6237;&#x7AEF;&#xFF1A;</p>
<ul>
<li>&#x5B58;&#x5728; <code>com.hazelcast.client.config.ClientConfig</code> bean&#x3002;</li>
<li><code>spring.hazelcast.config</code> &#x5C5E;&#x6027;&#x5B9A;&#x4E49;&#x7684;&#x914D;&#x7F6E;&#x6587;&#x4EF6;&#x3002;</li>
<li>&#x5B58;&#x5728; <code>hazelcast.client.config</code> &#x7CFB;&#x7EDF;&#x5C5E;&#x6027;&#x3002;</li>
<li>&#x5DE5;&#x4F5C;&#x76EE;&#x5F55;&#x4E2D;&#x6216; classpath &#x6839;&#x76EE;&#x5F55;&#x4E0B;&#x7684; <code>hazelcast-client.xml</code>&#x3002;</li>
</ul>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>Spring Boot &#x8FD8;&#x4E3A; Hazelcast &#x63D0;&#x4F9B;&#x4E86;<a href="#boot-features-caching-provider-hazelcast">&#x7F13;&#x5B58;&#x652F;&#x6301;</a>&#x3002;&#x5982;&#x679C;&#x542F;&#x7528;&#x4E86;&#x7F13;&#x5B58;&#xFF0C;<code>HazelcastInstance</code> &#x5C06;&#x81EA;&#x52A8;&#x5305;&#x88C5;&#x5728; <code>CacheManager</code> &#x5B9E;&#x73B0;&#x4E2D;&#x3002;</p>
</blockquote>
<p><a id="boot-features-quartz"></a></p>
<h2 id="40&#x3001;quartz-&#x8C03;&#x5EA6;&#x5668;">40&#x3001;Quartz &#x8C03;&#x5EA6;&#x5668;</h2>
<p>Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x51E0;&#x79CD;&#x4F7F;&#x7528; <a href="http://www.quartz-scheduler.org/" target="_blank">Quartz &#x8C03;&#x5EA6;&#x5668;</a>&#x7684;&#x4FBF;&#x6377;&#x65B9;&#x5F0F;&#xFF0C;&#x5B83;&#x4EEC;&#x6765;&#x81EA; <code>spring-boot-starter-quartz</code> starter&#x3002;&#x5982;&#x679C; Quartz &#x53EF;&#x7528;&#xFF0C;&#x5219; Spring Boot &#x5C06;&#x81EA;&#x52A8;&#x914D;&#x7F6E; <code>Scheduler</code>&#xFF08;&#x901A;&#x8FC7; <code>SchedulerFactoryBean</code> &#x62BD;&#x8C61;&#xFF09;&#x3002;</p>
<p>&#x81EA;&#x52A8;&#x9009;&#x53D6;&#x4EE5;&#x4E0B;&#x7C7B;&#x578B;&#x7684; Bean &#x5E76;&#x5C06;&#x5176;&#x4E0E; <code>Scheduler</code> &#x5173;&#x8054;&#x8D77;&#x6765;&#xFF1A;</p>
<ul>
<li><code>JobDetail</code>&#xFF1A;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A;&#x7279;&#x5B9A;&#x7684; job&#x3002;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>JobBuilder</code> API &#x6784;&#x5EFA; <code>JobDetail</code> &#x5B9E;&#x4F8B;&#x3002;</li>
<li><code>Calendar</code>&#x3002;</li>
<li><code>Trigger</code>&#xFF1A;&#x5B9A;&#x4E49;&#x4F55;&#x65F6;&#x89E6;&#x53D1; job&#x3002;</li>
</ul>
<p>&#x9ED8;&#x8BA4;&#x4F7F;&#x7528;&#x5185;&#x5B58;&#x5B58;&#x50A8;&#x65B9;&#x5F0F;&#x7684; <code>JobStore</code>&#x3002; &#x4F46;&#x5982;&#x679C;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E2D;&#x6709; <code>DataSource</code> bean&#xFF0C;&#x5E76;&#x4E14;&#x914D;&#x7F6E;&#x4E86; <code>spring.quartz.job-store-type</code> &#x5C5E;&#x6027;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x914D;&#x7F6E;&#x57FA;&#x4E8E; JDBC &#x7684;&#x5B58;&#x50A8;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.quartz.job-store-type</span><span class="token attr-value"><span class="token punctuation">=</span>jdbc</span>
</code></pre>
<p>&#x4F7F;&#x7528; JDBC &#x5B58;&#x50A8;&#x65F6;&#xFF0C;&#x53EF;&#x4EE5;&#x5728;&#x542F;&#x52A8;&#x65F6;&#x521D;&#x59CB;&#x5316; schema&#xFF08;&#x8868;&#x7ED3;&#x6784;&#xFF09;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.quartz.jdbc.initialize-schema</span><span class="token attr-value"><span class="token punctuation">=</span>always</span>
</code></pre>
<p><strong>&#x8B66;&#x544A;</strong></p>
<blockquote>
<p>&#x9ED8;&#x8BA4;&#x5C06;&#x4F7F;&#x7528; Quartz &#x5E93;&#x63D0;&#x4F9B;&#x7684;&#x6807;&#x51C6;&#x811A;&#x672C;&#x68C0;&#x6D4B;&#x5E76;&#x521D;&#x59CB;&#x5316;&#x6570;&#x636E;&#x5E93;&#x3002;&#x8FD9;&#x4E9B;&#x811A;&#x672C;&#x4F1A;&#x5220;&#x9664;&#x73B0;&#x6709;&#x8868;&#xFF0C;&#x5728;&#x6BCF;&#x6B21;&#x91CD;&#x542F;&#x65F6;&#x5220;&#x9664;&#x6240;&#x6709;&#x89E6;&#x53D1;&#x5668;&#x3002;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x8BBE;&#x7F6E; <code>spring.quartz.jdbc.schema</code> &#x5C5E;&#x6027;&#x6765;&#x63D0;&#x4F9B;&#x81EA;&#x5B9A;&#x4E49;&#x811A;&#x672C;&#x3002;</p>
</blockquote>
<p>&#x8981;&#x8BA9; Quartz &#x4F7F;&#x7528;&#x9664;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E3B; <code>DataSource</code> &#x4E4B;&#x5916;&#x7684; <code>DataSource</code>&#xFF0C;&#x8BF7;&#x58F0;&#x660E;&#x4E00;&#x4E2A; <code>DataSource</code> bean&#xFF0C;&#x4F7F;&#x7528; <code>@QuartzDataSource</code> &#x6CE8;&#x89E3;&#x5176; <code>@Bean</code> &#x65B9;&#x6CD5;&#x3002;&#x8FD9;&#x6837;&#x505A;&#x53EF;&#x786E;&#x4FDD; <code>SchedulerFactoryBean</code> &#x548C; schema &#x521D;&#x59CB;&#x5316;&#x90FD;&#x4F7F;&#x7528; Quartz &#x6307;&#x5B9A;&#x7684; <code>DataSource</code>&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x914D;&#x7F6E;&#x521B;&#x5EFA;&#x7684; job &#x4E0D;&#x4F1A;&#x8986;&#x76D6;&#x5DF2;&#x4ECE;&#x6301;&#x4E45; job &#x5B58;&#x50A8;&#x8BFB;&#x53D6;&#x7684;&#x5DF2;&#x6CE8;&#x518C;&#x7684; job&#x3002;&#x8981;&#x542F;&#x7528;&#x8986;&#x76D6;&#x73B0;&#x6709;&#x7684; job &#x5B9A;&#x4E49;&#xFF0C;&#x8BF7;&#x8BBE;&#x7F6E; <code>spring.quartz.overwrite-existing-jobs</code> &#x5C5E;&#x6027;&#x3002;</p>
<p>Quartz &#x8C03;&#x53D6;&#x5668;&#x914D;&#x7F6E;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.quartz</code> &#x5C5E;&#x6027;&#x548C; <code>SchedulerFactoryBeanCustomizer</code> bean &#x8FDB;&#x884C;&#x81EA;&#x5B9A;&#x4E49;&#xFF0C;&#x5B83;&#x4EEC;&#x5141;&#x8BB8;&#x4EE5;&#x7F16;&#x7A0B;&#x65B9;&#x5F0F;&#x7684; SchedulerFactoryBean &#x81EA;&#x5B9A;&#x4E49;&#x3002;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.quartz.properties.*</code> &#x81EA;&#x5B9A;&#x4E49;&#x9AD8;&#x7EA7; Quartz &#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x9700;&#x8981;&#x5F3A;&#x8C03;&#x7684;&#x662F;&#xFF0C;<code>Executor</code> bean &#x4E0E;&#x8C03;&#x5EA6;&#x7A0B;&#x5E8F;&#x6CA1;&#x6709;&#x5173;&#x8054;&#xFF0C;&#x56E0;&#x4E3A; Quartz &#x63D0;&#x4F9B;&#x4E86;&#x901A;&#x8FC7; <code>spring.quartz.properties</code> &#x914D;&#x7F6E;&#x8C03;&#x5EA6;&#x5668;&#x7684;&#x65B9;&#x6CD5;&#x3002;&#x5982;&#x679C;&#x9700;&#x8981;&#x81EA;&#x5B9A;&#x4E49;&#x6267;&#x884C;&#x5668;&#xFF0C;&#x8BF7;&#x8003;&#x8651;&#x5B9E;&#x73B0; <code>SchedulerFactoryBeanCustomizer</code>&#x3002;</p>
</blockquote>
<p>job &#x53EF;&#x4EE5;&#x5B9A;&#x4E49; <code>setter</code> &#x4EE5;&#x6CE8;&#x5165;&#x6570;&#x636E;&#x6620;&#x5C04;&#x5C5E;&#x6027;&#x3002;&#x4E5F;&#x53EF;&#x4EE5;&#x4EE5;&#x7C7B;&#x4F3C;&#x7684;&#x65B9;&#x5F0F;&#x6CE8;&#x5165;&#x5E38;&#x89C4;&#x7684; bean&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SampleJob</span> <span class="token keyword">extends</span> <span class="token class-name">QuartzJobBean</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token class-name">MyService</span> myService<span class="token punctuation">;</span>

    <span class="token keyword">private</span> <span class="token class-name">String</span> name<span class="token punctuation">;</span>

    <span class="token comment">// Inject &quot;MyService&quot; bean</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setMyService</span><span class="token punctuation">(</span><span class="token class-name">MyService</span> myService<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

    <span class="token comment">// Inject the &quot;name&quot; job data property</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setName</span><span class="token punctuation">(</span><span class="token class-name">String</span> name<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">protected</span> <span class="token keyword">void</span> <span class="token function">executeInternal</span><span class="token punctuation">(</span><span class="token class-name">JobExecutionContext</span> context<span class="token punctuation">)</span>
            <span class="token keyword">throws</span> <span class="token class-name">JobExecutionException</span> <span class="token punctuation">{</span>
        <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-task-execution-scheduling"></a></p>
<h2 id="41&#x3001;&#x4EFB;&#x52A1;&#x6267;&#x884C;&#x4E0E;&#x8C03;&#x5EA6;">41&#x3001;&#x4EFB;&#x52A1;&#x6267;&#x884C;&#x4E0E;&#x8C03;&#x5EA6;</h2>
<p>&#x5728;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x6CA1;&#x6709; <code>Executor</code> bean &#x7684;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Spring Boot &#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A;&#x6709;&#x5408;&#x7406;&#x9ED8;&#x8BA4;&#x503C;&#x7684; <code>ThreadPoolTask&#x200B;&#x200B;Executor</code>&#xFF0C;&#x5B83;&#x53EF;&#x4EE5;&#x81EA;&#x52A8;&#x4E0E;&#x5F02;&#x6B65;&#x4EFB;&#x52A1;&#x6267;&#x884C;&#xFF08;<code>@EnableAsync</code>&#xFF09;&#x548C; Spring MVC &#x5F02;&#x6B65;&#x8BF7;&#x6C42;&#x5904;&#x7406;&#x76F8;&#x5173;&#x8054;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>

&#x5982;&#x679C;&#x60A8;&#x5728;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x5B9A;&#x4E49;&#x4E86;&#x81EA;&#x5B9A;&#x4E49; `Executor`&#xFF0C;&#x5219;&#x5E38;&#x89C4;&#x4EFB;&#x52A1;&#x6267;&#x884C;&#xFF08;&#x5373; `@EnableAsync`&#xFF09;&#x5C06;&#x900F;&#x660E;&#x5730;&#x4F7F;&#x7528;&#x5B83;&#xFF0C;&#x4F46;&#x4E0D;&#x4F1A;&#x914D;&#x7F6E; Spring MVC &#x652F;&#x6301;&#xFF0C;&#x56E0;&#x4E3A;&#x5B83;&#x9700;&#x8981; `AsyncTaskExecutor` &#x5B9E;&#x73B0;&#xFF08;&#x540D;&#x4E3A; `applicationTaskExecutor`&#xFF09;&#x3002;&#x6839;&#x636E;&#x60A8;&#x7684;&#x76EE;&#x6807;&#x5B89;&#x6392;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x5C06; `Executor` &#x66F4;&#x6539;&#x4E3A; `ThreadPoolTask&#x200B;&#x200B;Executor`&#xFF0C;&#x6216;&#x8005;&#x5B9A;&#x4E49; `Executor&#x7684;ThreadPoolTask&#x200B;&#x200B;Executor` &#x548C; `AsyncConfigurer` &#x6765;&#x5305;&#x88C5;&#x81EA;&#x5B9A;&#x4E49;&#x7684; `Executor`&#x3002;

&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; `TaskExecutorBuilder` &#x6765;&#x8F7B;&#x677E;&#x521B;&#x5EFA;&#x5B9E;&#x4F8B;&#xFF0C;&#x4EE5;&#x590D;&#x5236;&#x9ED8;&#x8BA4;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;

</blockquote>

<p>&#x7EBF;&#x7A0B;&#x6C60;&#x4F7F;&#x7528; 8 &#x4E2A;&#x6838;&#x5FC3;&#x7EBF;&#x7A0B;&#xFF0C;&#x53EF;&#x6839;&#x636E;&#x8D1F;&#x8F7D;&#x60C5;&#x51B5;&#x589E;&#x52A0;&#x548C;&#x51CF;&#x5C11;&#x3002;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.task.execution</code> &#x547D;&#x540D;&#x7A7A;&#x95F4;&#x5BF9;&#x8FD9;&#x4E9B;&#x9ED8;&#x8BA4;&#x8BBE;&#x7F6E;&#x8FDB;&#x884C;&#x5FAE;&#x8C03;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.task.execution.pool.max-threads</span><span class="token attr-value"><span class="token punctuation">=</span>16</span>
<span class="token constant">spring.task.execution.pool.queue-capacity</span><span class="token attr-value"><span class="token punctuation">=</span>100</span>
<span class="token constant">spring.task.execution.pool.keep-alive</span><span class="token attr-value"><span class="token punctuation">=</span>10s</span>
</code></pre>
<p>&#x8FD9;&#x4F1A;&#x5C06;&#x7EBF;&#x7A0B;&#x6C60;&#x66F4;&#x6539;&#x4E3A;&#x4F7F;&#x7528;&#x6709;&#x754C;&#x961F;&#x5217;&#xFF0C;&#x5728;&#x961F;&#x5217;&#x6EE1;&#xFF08;100 &#x4E2A;&#x4EFB;&#x52A1;&#xFF09;&#x65F6;&#xFF0C;&#x7EBF;&#x7A0B;&#x6C60;&#x5C06;&#x589E;&#x52A0;&#x5230;&#x6700;&#x591A; 16 &#x4E2A;&#x7EBF;&#x7A0B;&#x3002;&#x5F53;&#x7EBF;&#x7A0B;&#x5728;&#x95F2;&#x7F6E;10 &#x79D2;&#xFF08;&#x800C;&#x4E0D;&#x662F;&#x9ED8;&#x8BA4;&#x7684; 60 &#x79D2;&#xFF09;&#x65F6;&#x56DE;&#x6536;&#x7EBF;&#x7A0B;&#xFF0C;&#x6C60;&#x7684;&#x6536;&#x7F29;&#x66F4;&#x4E3A;&#x660E;&#x663E;&#x3002;</p>
<p>&#x5982;&#x679C;&#x9700;&#x8981;&#x4E0E;&#x8C03;&#x5EA6;&#x4EFB;&#x52A1;&#x6267;&#x884C;&#xFF08;<code>@EnableScheduling</code>&#xFF09;&#x76F8;&#x5173;&#x8054;&#xFF0C;&#x53EF;&#x4EE5;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4E00;&#x4E2A; <code>ThreadPoolTaskScheduler</code>&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x7EBF;&#x7A0B;&#x6C60;&#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x7EBF;&#x7A0B;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.task.scheduling</code> &#x547D;&#x540D;&#x7A7A;&#x95F4;&#x5BF9;&#x8FD9;&#x4E9B;&#x8BBE;&#x7F6E;&#x8FDB;&#x884C;&#x5FAE;&#x8C03;&#x3002;</p>
<p>&#x5982;&#x679C;&#x9700;&#x8981;&#x521B;&#x5EFA;&#x81EA;&#x5B9A;&#x4E49;&#x6267;&#x884C;&#x5668;&#x6216;&#x8C03;&#x5EA6;&#x5668;&#xFF0C;&#x5219;&#x5728;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>TaskExecutorBuilder</code> bean &#x548C; <code>TaskSchedulerBuilder</code> bean&#x3002;</p>
<p><a id="boot-features-integration"></a></p>
<h2 id="42&#x3001;spring-integration">42&#x3001;Spring Integration</h2>
<p>Spring Boot &#x4E3A; <a href="https://projects.spring.io/spring-integration/" target="_blank">Spring Integration</a> &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E9B;&#x4FBF;&#x6377;&#x7684;&#x4F7F;&#x7528;&#x65B9;&#x5F0F;&#xFF0C;&#x5B83;&#x4EEC;&#x5305;&#x542B;&#x5728; <code>spring-boot-starter-integration</code> starter &#x4E2D;&#x3002;Spring Integration &#x4E3A;&#x6D88;&#x606F;&#x4F20;&#x9012;&#x4EE5;&#x53CA;&#x5176;&#x4ED6;&#x4F20;&#x8F93;&#xFF08;&#x5982; HTTP&#x3001;TCP &#x7B49;&#xFF09;&#x63D0;&#x4F9B;&#x4E86;&#x62BD;&#x8C61;&#x3002;&#x5982;&#x679C; classpath &#x4E0A;&#x5B58;&#x5728; Spring Integration&#xFF0C;&#x5219; Spring Boot &#x4F1A;&#x901A;&#x8FC7; <code>@EnableIntegration</code> &#x6CE8;&#x89E3;&#x5BF9;&#x5176;&#x8FDB;&#x884C;&#x521D;&#x59CB;&#x5316;&#x3002;</p>
<p>Spring Boot &#x8FD8;&#x914D;&#x7F6E;&#x4E86;&#x4E00;&#x4E9B;&#x7531;&#x5176;&#x4ED6; Spring Integration &#x6A21;&#x5757;&#x89E6;&#x53D1;&#x7684;&#x529F;&#x80FD;&#x3002;&#x5982;&#x679C; <code>spring-integration-jmx</code> &#x4E5F;&#x5728; classpath &#x4E0A;&#xFF0C;&#x5219;&#x6D88;&#x606F;&#x5904;&#x7406;&#x7EDF;&#x8BA1;&#x4FE1;&#x606F;&#x5C06;&#x901A;&#x8FC7; JMX &#x53D1;&#x5E03;&#x3002;&#x5982;&#x679C; <code>spring-integration-jdbc</code> &#x53EF;&#x7528;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5728;&#x542F;&#x52A8;&#x65F6;&#x521B;&#x5EFA;&#x9ED8;&#x8BA4;&#x6570;&#x636E;&#x5E93;&#x6A21;&#x5F0F;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.integration.jdbc.initialize-schema</span><span class="token attr-value"><span class="token punctuation">=</span>always</span>
</code></pre>
<p>&#x6709;&#x5173;&#x66F4;&#x591A;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.2.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java" target="_blank">IntegrationAutoConfiguration</a> &#x548C; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.2.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationProperties.java" target="_blank">IntegrationProperties</a> &#x7C7B;&#x3002;</p>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5982;&#x679C;&#x5B58;&#x5728; Micrometer <code>meterRegistry</code> bean&#xFF0C;&#x5219; Micrometer &#x5C06;&#x7BA1;&#x7406; Spring Integration &#x7684;&#x6307;&#x6807;&#x3002;&#x5982;&#x679C;&#x60A8;&#x5E0C;&#x671B;&#x4F7F;&#x7528;&#x65E7;&#x7248; Spring Integration &#x5EA6;&#x91CF;&#xFF0C;&#x8BF7;&#x5C06; <code>DefaultMetricsFactory</code> bean &#x6DFB;&#x52A0;&#x5230;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x3002;</p>
<p><a id="boot-features-session"></a></p>
<h2 id="43&#x3001;spring-session">43&#x3001;Spring Session</h2>
<p>Spring Boot &#x4E3A;&#x5404;&#x79CD;&#x6570;&#x636E;&#x5B58;&#x50A8;&#x63D0;&#x4F9B; <a href="https://projects.spring.io/spring-session/" target="_blank">Spring Session</a> &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x5728;&#x6784;&#x5EFA; Servlet Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x65F6;&#xFF0C;&#x53EF;&#x4EE5;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4EE5;&#x4E0B;&#x5B58;&#x50A8;&#xFF1A;</p>
<ul>
<li>JDBC</li>
<li>Redis</li>
<li>Hazelcast</li>
<li>MongoDB</li>
</ul>
<p>&#x6784;&#x5EFA;&#x54CD;&#x5E94;&#x5F0F; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x65F6;&#xFF0C;&#x53EF;&#x4EE5;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4EE5;&#x4E0B;&#x5B58;&#x50A8;&#xFF1A;</p>
<ul>
<li>Redis</li>
<li>MongoDB</li>
</ul>
<p>&#x5982;&#x679C; classpath &#x4E0A;&#x5B58;&#x5728;&#x5355;&#x4E2A; Spring Session &#x6A21;&#x5757;&#xFF0C;&#x5219; Spring Boot &#x4F1A;&#x81EA;&#x52A8;&#x4F7F;&#x7528;&#x8BE5;&#x5B58;&#x50A8;&#x5B9E;&#x73B0;&#x3002;&#x5982;&#x679C;&#x60A8;&#x6709;&#x591A;&#x4E2A;&#x5B9E;&#x73B0;&#xFF0C;&#x5219;&#x5FC5;&#x987B;&#x9009;&#x62E9;&#x8981;&#x7528;&#x4E8E;&#x5B58;&#x50A8;&#x4F1A;&#x8BDD;&#x7684; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.2.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/StoreType.java" target="_blank"><code>StoreType</code></a>&#x3002; &#x4F8B;&#x5982;&#xFF0C;&#x8981;&#x4F7F;&#x7528; JDBC &#x4F5C;&#x4E3A;&#x540E;&#x7AEF;&#x5B58;&#x50A8;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x6309;&#x5982;&#x4E0B;&#x65B9;&#x5F0F;&#x914D;&#x7F6E;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.session.store-type</span><span class="token attr-value"><span class="token punctuation">=</span>jdbc</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x53EF;&#x4EE5;&#x5C06; <code>store-type</code> &#x8BBE;&#x7F6E;&#x4E3A; <code>none</code> &#x6765;&#x7981;&#x7528; Spring Session&#x3002;</p>
</blockquote>
<p>&#x6BCF;&#x4E2A; store &#x90FD;&#x6709;&#x81EA;&#x5DF1;&#x7684;&#x989D;&#x5916;&#x8BBE;&#x7F6E;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x53EF;&#x4EE5;&#x4E3A; JDBC &#x5B58;&#x50A8;&#x5B9A;&#x5236;&#x8868;&#x7684;&#x540D;&#x79F0;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.session.jdbc.table-name</span><span class="token attr-value"><span class="token punctuation">=</span>SESSIONS</span>
</code></pre>
<p>&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring.session.timeout</code> &#x5C5E;&#x6027;&#x6765;&#x8BBE;&#x7F6E;&#x4F1A;&#x8BDD;&#x7684;&#x8D85;&#x65F6;&#x65F6;&#x95F4;&#x3002;&#x5982;&#x679C;&#x672A;&#x8BBE;&#x7F6E;&#x8BE5;&#x5C5E;&#x6027;&#xFF0C;&#x5219;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x5C06;&#x4F7F;&#x7528; <code>server.servlet.session.timeout</code> &#x7684;&#x503C;&#x3002;</p>
<p><a id="boot-features-jmx"></a></p>
<h2 id="44&#x3001;&#x901A;&#x8FC7;-jmx-&#x76D1;&#x63A7;&#x548C;&#x7BA1;&#x7406;">44&#x3001;&#x901A;&#x8FC7; JMX &#x76D1;&#x63A7;&#x548C;&#x7BA1;&#x7406;</h2>
<p>Java Management Extensions&#xFF08;JMX&#xFF0C;Java &#x7BA1;&#x7406;&#x6269;&#x5C55;&#xFF09;&#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x79CD;&#x76D1;&#x89C6;&#x548C;&#x7BA1;&#x7406;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x6807;&#x51C6;&#x673A;&#x5236;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Spring Boot &#x4F1A;&#x521B;&#x5EFA;&#x4E00;&#x4E2A; ID &#x4E3A; <code>mbeanServer</code> &#x7684; <code>MBeanServer</code> bean&#xFF0C;&#x5E76;&#x66B4;&#x9732;&#x4F7F;&#x7528; Spring JMX &#x6CE8;&#x89E3;&#xFF08;<code>@ManagedResource</code>&#x3001;<code>@ManagedAttribute</code> &#x6216; <code>@ManagedOperation</code>&#xFF09;&#x7684; bean&#x3002;</p>
<p>&#x6709;&#x5173;&#x66F4;&#x591A;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.2.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jmx/JmxAutoConfiguration.java" target="_blank"><code>JmxAutoConfiguration</code></a> &#x7C7B;&#x3002;</p>
<p><a id="boot-features-testing"></a></p>
<h2 id="45&#x3001;&#x6D4B;&#x8BD5;">45&#x3001;&#x6D4B;&#x8BD5;</h2>
<p><a id="boot-features-websockets"></a></p>
<h2 id="46&#x3001;websocket">46&#x3001;WebSocket</h2>
<p>Spring Boot &#x4E3A;&#x5185;&#x5D4C;&#x5F0F; Tomcat&#x3001;Jetty &#x548C; Undertow &#x63D0;&#x4F9B;&#x4E86; WebSocket &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x5982;&#x679C;&#x5C06; war &#x6587;&#x4EF6;&#x90E8;&#x7F72;&#x5230;&#x72EC;&#x7ACB;&#x5BB9;&#x5668;&#xFF0C;&#x5219; Spring Boot &#x5047;&#x5B9A;&#x5BB9;&#x5668;&#x8D1F;&#x8D23;&#x914D;&#x7F6E;&#x5176; WebSocket &#x652F;&#x6301;&#x3002;</p>
<p>Spring Framework &#x4E3A; MVC Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x63D0;&#x4F9B;&#x4E86;<a href="https://docs.spring.io/spring/docs/5.1.4.RELEASE/spring-framework-reference/web.html#websocket" target="_blank">&#x4E30;&#x5BCC;&#x7684; WebSocket &#x652F;&#x6301;</a>&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7; <code>spring-boot-starter-websocket</code> &#x6A21;&#x5757;&#x8F7B;&#x677E;&#x8BBF;&#x95EE;&#x3002;</p>
<p>WebSocket &#x652F;&#x6301;&#x4E5F;&#x53EF;&#x7528;&#x4E8E;<a href="https://docs.spring.io/spring/docs/5.1.4.RELEASE/spring-framework-reference/web-reactive.html#webflux-websocket" target="_blank">&#x54CD;&#x5E94;&#x5F0F; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;</a>&#xFF0C;&#x5E76;&#x4E14;&#x5F15;&#x5165; WebSocket API &#x4EE5;&#x53CA; <code>spring-boot-starter-webflux</code>&#xFF1A;</p>
<pre class="language-"><code class="lang-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>javax.websocket<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>javax.websocket-api<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre>
<p><a id="boot-features-webservices"></a></p>
<h2 id="47&#x3001;web-service">47&#x3001;Web Service</h2>
<p>Spring Boot &#x63D0;&#x4F9B; Web Service &#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x56E0;&#x6B64;&#x60A8;&#x8981;&#x505A;&#x7684;&#x5C31;&#x662F;&#x5B9A;&#x4E49; <code>Endpoints</code>&#x3002;</p>
<p>&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>spring-boot-starter-webservices</code> &#x6A21;&#x5757;&#x8F7B;&#x677E;&#x8BBF;&#x95EE; <a href="https://docs.spring.io/spring-ws/docs/3.0.6.RELEASE/reference/" target="_blank">Spring Web Service &#x529F;&#x80FD;</a>&#x3002;</p>
<p>&#x53EF;&#x4EE5;&#x5206;&#x522B;&#x4E3A; WSDL &#x548C; XSD &#x81EA;&#x52A8;&#x521B;&#x5EFA; <code>SimpleWsdl11Definition</code> &#x548C; <code>SimpleXsdSchema</code> bean&#x3002;&#x4E3A;&#x6B64;&#xFF0C;&#x8BF7;&#x914D;&#x7F6E;&#x5176;&#x4F4D;&#x7F6E;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">spring.webservices.wsdl-locations</span><span class="token attr-value"><span class="token punctuation">=</span>classpath:/wsdl</span>
</code></pre>
<p><a id="boot-features-webservices-template"></a></p>
<h3 id="471&#x3001;&#x4F7F;&#x7528;-webservicetemplate-&#x8C03;&#x7528;-web-service">47.1&#x3001;&#x4F7F;&#x7528; <code>WebServiceTemplate</code> &#x8C03;&#x7528; Web Service</h3>
<p>&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x4ECE;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x8C03;&#x7528;&#x8FDC;&#x7A0B; Web &#x670D;&#x52A1;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>WebServiceTemplate</code> &#x7C7B;&#x3002;&#x7531;&#x4E8E; <code>WebServiceTemplate</code> &#x5B9E;&#x4F8B;&#x5728;&#x4F7F;&#x7528;&#x4E4B;&#x524D;&#x901A;&#x5E38;&#x9700;&#x8981;&#x8FDB;&#x884C;&#x81EA;&#x5B9A;&#x4E49;&#xFF0C;&#x56E0;&#x6B64; Spring Boot &#x4E0D;&#x63D0;&#x4F9B;&#x4EFB;&#x4F55;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684; <code>WebServiceTemplate</code> bean&#x3002;&#x4F46;&#x662F;&#xFF0C;&#x5B83;&#x4F1A;&#x81EA;&#x52A8;&#x914D;&#x7F6E; <code>WebServiceTemplateBuilder</code>&#xFF0C;&#x53EF;&#x5728;&#x9700;&#x8981;&#x521B;&#x5EFA; <code>WebServiceTemplate</code> &#x5B9E;&#x4F8B;&#x65F6;&#x4F7F;&#x7528;&#x3002;</p>
<p>&#x4EE5;&#x4E0B;&#x4EE3;&#x7801;&#x4E3A;&#x4E00;&#x4E2A;&#x5178;&#x578B;&#x793A;&#x4F8B;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Service</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyService</span> <span class="token punctuation">{</span>

    <span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">WebServiceTemplate</span> webServiceTemplate<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token class-name">MyService</span><span class="token punctuation">(</span><span class="token class-name">WebServiceTemplateBuilder</span> webServiceTemplateBuilder<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>webServiceTemplate <span class="token operator">=</span> webServiceTemplateBuilder<span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token class-name">DetailsResp</span> <span class="token function">someWsCall</span><span class="token punctuation">(</span><span class="token class-name">DetailsReq</span> detailsReq<span class="token punctuation">)</span> <span class="token punctuation">{</span>
         <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token class-name">DetailsResp</span><span class="token punctuation">)</span> <span class="token keyword">this</span><span class="token punctuation">.</span>webServiceTemplate<span class="token punctuation">.</span><span class="token function">marshalSendAndReceive</span><span class="token punctuation">(</span>detailsReq<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">SoapActionCallback</span><span class="token punctuation">(</span>ACTION<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;<code>WebServiceTemplateBuilder</code> &#x4F7F;&#x7528; classpath &#x4E0A;&#x7684;&#x53EF;&#x7528; HTTP &#x5BA2;&#x6237;&#x7AEF;&#x5E93;&#x68C0;&#x6D4B;&#x5408;&#x9002;&#x7684;&#x57FA;&#x4E8E; HTTP &#x7684; <code>WebServiceMessageSender</code>&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x6309;&#x5982;&#x4E0B;&#x65B9;&#x5F0F;&#x81EA;&#x5B9A;&#x4E49;&#x8BFB;&#x53D6;&#x548C;&#x8FDE;&#x63A5;&#x7684;&#x8D85;&#x65F6;&#x65F6;&#x95F4;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Bean</span>
<span class="token keyword">public</span> <span class="token class-name">WebServiceTemplate</span> <span class="token function">webServiceTemplate</span><span class="token punctuation">(</span><span class="token class-name">WebServiceTemplateBuilder</span> builder<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">return</span> builder<span class="token punctuation">.</span><span class="token function">messageSenders</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">HttpWebServiceMessageSenderBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">setConnectTimeout</span><span class="token punctuation">(</span><span class="token number">5000</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setReadTimeout</span><span class="token punctuation">(</span><span class="token number">2000</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">build</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-developing-auto-configuration"></a></p>
<h2 id="49&#x3001;&#x521B;&#x5EFA;&#x81EA;&#x5DF1;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;">49&#x3001;&#x521B;&#x5EFA;&#x81EA;&#x5DF1;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;</h2>
<p>&#x5982;&#x679C;&#x60A8;&#x5728;&#x516C;&#x53F8;&#x8D1F;&#x8D23;&#x5F00;&#x53D1;&#x516C;&#x5171;&#x7C7B;&#x5E93;&#xFF0C;&#x6216;&#x8005;&#x5982;&#x679C;&#x60A8;&#x5728;&#x5F00;&#x53D1;&#x4E00;&#x4E2A;&#x5F00;&#x6E90;&#x6216;&#x5546;&#x4E1A;&#x5E93;&#xFF0C;&#x60A8;&#x53EF;&#x80FD;&#x5E0C;&#x671B;&#x5F00;&#x53D1;&#x81EA;&#x5DF1;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7C7B;&#x53EF;&#x4EE5;&#x6346;&#x7ED1;&#x5728;&#x5916;&#x90E8; jar &#x4E2D;&#xFF0C;&#x4ED6;&#x4ECD;&#x7136;&#x53EF;&#x4EE5;&#x88AB; Spring Boot &#x83B7;&#x53D6;&#x3002;</p>
<p>&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x53EF;&#x4EE5;&#x4E0E;&#x63D0;&#x4F9B;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4EE3;&#x7801;&#x7684; starter &#x4EE5;&#x53CA;&#x60A8;&#x5C06;&#x4F7F;&#x7528;&#x7684;&#x7C7B;&#x5E93;&#x5E93;&#x76F8;&#x5173;&#x8054;&#x3002;&#x6211;&#x4EEC;&#x9996;&#x5148;&#x4ECB;&#x7ECD;&#x6784;&#x5EFA;&#x81EA;&#x5DF1;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x9700;&#x8981;&#x4E86;&#x89E3;&#x7684;&#x5185;&#x5BB9;&#xFF0C;&#x7136;&#x540E;&#x6211;&#x4EEC;&#x5C06;&#x7EE7;&#x7EED;&#x4ECB;&#x7ECD;<a href="#boot-features-custom-starter">&#x521B;&#x5EFA;&#x81EA;&#x5B9A;&#x4E49; starter &#x6240;&#x9700;&#x7684;&#x6B65;&#x9AA4;</a>&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x8FD9;&#x91CC;&#x6709;&#x4E00;&#x4E2A;<a href="https://github.com/snicoll-demos/spring-boot-master-auto-configuration" target="_blank">&#x6F14;&#x793A;&#x9879;&#x76EE;</a>&#x5C55;&#x793A;&#x4E86;&#x5982;&#x4F55;&#x9010;&#x6B65;&#x521B;&#x5EFA; starter&#x3002;</p>
</blockquote>
<p><a id="boot-features-understanding-auto-configured-beans"></a></p>
<h3 id="491&#x3001;&#x7406;&#x89E3;&#x81EA;&#x5B9A;&#x914D;&#x7F6E;-bean">49.1&#x3001;&#x7406;&#x89E3;&#x81EA;&#x5B9A;&#x914D;&#x7F6E; Bean</h3>
<p>&#x5728;&#x5185;&#x90E8;&#xFF0C;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4F7F;&#x7528;&#x4E86;&#x6807;&#x51C6;&#x7684; <code>@Configuration</code> &#x7C7B;&#x6765;&#x5B9E;&#x73B0;&#x3002;<code>@Conditional</code> &#x6CE8;&#x89E3;&#x7528;&#x4E8E;&#x7EA6;&#x675F;&#x4F55;&#x65F6;&#x5E94;&#x7528;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x901A;&#x5E38;&#xFF0C;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7C7B;&#x4F7F;&#x7528; <code>@ConditionalOnClass</code> &#x548C; <code>@ConditionalOnMissingBean</code> &#x6CE8;&#x89E3;&#x3002;&#x8FD9;&#x53EF;&#x786E;&#x4FDD;&#x4EC5;&#x5728;&#x627E;&#x5230;&#x76F8;&#x5173;&#x7C7B;&#x65F6;&#x4EE5;&#x53CA;&#x672A;&#x58F0;&#x660E;&#x60A8;&#x81EA;&#x5DF1;&#x7684; <code>@Configuration</code> &#x65F6;&#x624D;&#x5E94;&#x7528;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;</p>
<p>&#x60A8;&#x53EF;&#x4EE5;&#x6D4F;&#x89C8; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.3.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure" target="_blank"><code>spring-boot-autoconfigure</code></a> &#x7684;&#x6E90;&#x4EE3;&#x7801;&#xFF0C;&#x4EE5;&#x67E5;&#x770B; Spring &#x63D0;&#x4F9B;&#x7684; <code>@Configuration</code> &#x7C7B;&#xFF08;&#x8BF7;&#x53C2;&#x9605; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.3.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories" target="_blank"><code>META-INF/spring.factories</code></a> &#x6587;&#x4EF6;&#xFF09;&#x3002;</p>
<p><a id="boot-features-locating-auto-configuration-candidates"></a></p>
<h3 id="492&#x3001;&#x627E;&#x5230;&#x5019;&#x9009;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;">49.2&#x3001;&#x627E;&#x5230;&#x5019;&#x9009;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;</h3>
<p>Spring Boot &#x4F1A;&#x68C0;&#x67E5;&#x5DF2;&#x53D1;&#x5E03; jar &#x4E2D;&#x662F;&#x5426;&#x5B58;&#x5728; <code>META-INF/spring.factories</code> &#x6587;&#x4EF6;&#x3002;&#x8BE5;&#x6587;&#x4EF6;&#x5E94;&#x5217;&#x51FA; <code>EnableAutoConfiguration</code> key &#x4E0B;&#x7684;&#x914D;&#x7F6E;&#x7C7B;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-ini"><span class="token constant">org.springframework.boot.autoconfigure.EnableAutoConfiguration</span><span class="token attr-value"><span class="token punctuation">=</span>\</span>
com.mycorp.libx.autoconfigure.LibXAutoConfiguration,\
com.mycorp.libx.autoconfigure.LibXWebAutoConfiguration
</code></pre>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p><strong>&#x5FC5;&#x987B;</strong>&#x4EE5;&#x8FD9;&#x79CD;&#x65B9;&#x5F0F;&#x52A0;&#x8F7D;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;&#x786E;&#x4FDD;&#x5B83;&#x4EEC;&#x5728;&#x7279;&#x5B9A;&#x7684;&#x5305;&#x7A7A;&#x95F4;&#x4E2D;&#x5B9A;&#x4E49;&#xFF0C;&#x5E76;&#x4E14;&#x5B83;&#x4EEC;&#x4E0D;&#x80FD;&#x662F;&#x7EC4;&#x4EF6;&#x626B;&#x63CF;&#x7684;&#x76EE;&#x6807;&#x3002;&#x6B64;&#x5916;&#xFF0C;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7C7B;&#x4E0D;&#x5E94;&#x542F;&#x7528;&#x7EC4;&#x4EF6;&#x626B;&#x63CF;&#x4EE5;&#x67E5;&#x627E;&#x5176;&#x4ED6;&#x7EC4;&#x4EF6;&#x3002;&#x5E94;&#x8BE5;&#x4F7F;&#x7528;&#x7279;&#x5B9A;&#x7684;<code>@Imports</code> &#x6765;&#x4EE3;&#x66FF;&#x3002;</p>
</blockquote>
<p>&#x5982;&#x679C;&#x9700;&#x8981;&#x6309;&#x7279;&#x5B9A;&#x987A;&#x5E8F;&#x5E94;&#x7528;&#x914D;&#x7F6E;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.3.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigureAfter.java" target="_blank"><code>@AutoConfigureAfter</code></a> &#x6216; <a href="https://github.com/spring-projects/spring-boot/tree/v2.1.3.RELEASE/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/AutoConfigureBefore.java" target="_blank"><code>@AutoConfigureBefore</code></a> &#x6CE8;&#x89E3;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x63D0;&#x4F9B;&#x7279;&#x5B9A;&#x4E8E; Web &#x7684;&#x914D;&#x7F6E;&#xFF0C;&#x5219;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x5728;<code>WebMvcAutoConfiguration</code> &#x4E4B;&#x540E;&#x5E94;&#x7528;&#x60A8;&#x7684;&#x7C7B;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x60F3;&#x6392;&#x5E8F;&#x67D0;&#x4E9B;&#x4E0D;&#x5E94;&#x8BE5;&#x5F7C;&#x6B64;&#x76F4;&#x63A5;&#x4E86;&#x89E3;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x60A8;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>@AutoConfigureOrder</code>&#x3002;&#x8BE5;&#x6CE8;&#x89E3;&#x4E0E;&#x5E38;&#x89C4; <code>@Order</code> &#x6CE8;&#x89E3;&#x6709;&#x76F8;&#x540C;&#x7684;&#x8BED;&#x4E49;&#xFF0C;&#x4F46;&#x5B83;&#x4E3A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7C7B;&#x63D0;&#x4F9B;&#x4E86;&#x4E13;&#x7528;&#x987A;&#x5E8F;&#x3002;</p>
<p><a id="boot-features-condition-annotations"></a></p>
<h3 id="493&#x3001;&#x6761;&#x4EF6;&#x6CE8;&#x89E3;">49.3&#x3001;&#x6761;&#x4EF6;&#x6CE8;&#x89E3;</h3>
<p>&#x60A8;&#x51E0;&#x4E4E;&#x603B;&#x5E0C;&#x671B;&#x5728;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7C7B;&#x4E2D;&#x5305;&#x542B;&#x4E00;&#x4E2A;&#x6216;&#x591A;&#x4E2A; <code>@Conditional</code> &#x6CE8;&#x89E3;&#x3002;<code>@ConditionalOnMissingBean</code> &#x662F;&#x4E00;&#x4E2A;&#x5E38;&#x7528;&#x7684;&#x6CE8;&#x89E3;&#xFF0C;&#x5176;&#x5141;&#x8BB8;&#x5F00;&#x53D1;&#x4EBA;&#x5458;&#x5728;&#x5BF9;&#x60A8;&#x7684;&#x9ED8;&#x8BA4;&#x503C;&#x4E0D;&#x6EE1;&#x610F;&#x7528;&#x4E8E;&#x8986;&#x76D6;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x3002;</p>
<p>Spring Boot &#x5305;&#x542B;&#x8BB8;&#x591A; <code>@Conditional</code> &#x6CE8;&#x89E3;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x6CE8;&#x89E3; <code>@Configuration</code> &#x7C7B;&#x6216;&#x5355;&#x72EC;&#x7684; <code>@Bean</code> &#x65B9;&#x6CD5;&#x5728;&#x60A8;&#x81EA;&#x5DF1;&#x7684;&#x4EE3;&#x7801;&#x4E2D;&#x590D;&#x7528;&#x5B83;&#x4EEC;&#x3002;&#x8FD9;&#x4E9B;&#x6CE8;&#x89E3;&#x5305;&#x62EC;&#xFF1A;</p>
<ul>
<li><a href="#boot-features-class-conditions">&#x7B2C; 49.3.1 &#x8282;&#xFF0C;&#x7C7B;&#x6761;&#x4EF6;</a></li>
<li><a href="#boot-features-bean-conditions">&#x7B2C; 49.3.2 &#x8282;&#xFF0C;Bean &#x6761;&#x4EF6;</a></li>
<li><a href="#boot-features-property-conditions">&#x7B2C; 49.3.3 &#x8282;&#xFF0C;&#x5C5E;&#x6027;&#x6761;&#x4EF6;</a></li>
<li><a href="#boot-features-resource-conditions">&#x7B2C; 49.3.4 &#x8282;&#xFF0C;&#x8D44;&#x6E90;&#x6761;&#x4EF6;</a></li>
<li><a href="#boot-features-web-application-conditions">&#x7B2C; 49.3.5 &#x8282;&#xFF0C;Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x6761;&#x4EF6;</a></li>
<li><a href="#boot-features-spel-conditions">&#x7B2C; 49.3.6 &#x8282;&#xFF0C;SpEL &#x8868;&#x8FBE;&#x5F0F;&#x6761;&#x4EF6;</a></li>
</ul>
<p><a id="boot-features-class-conditions"></a></p>
<h4 id="4931&#x3001;&#x7C7B;&#x6761;&#x4EF6;">49.3.1&#x3001;&#x7C7B;&#x6761;&#x4EF6;</h4>
<p><code>@ConditionalOnClass</code> &#x548C; <code>@ConditionalOnMissingClass</code> &#x6CE8;&#x89E3;&#x5141;&#x8BB8;&#x6839;&#x636E;&#x7279;&#x5B9A;&#x7C7B;&#x7684;&#x662F;&#x5426;&#x5B58;&#x5728;&#x6765;&#x5305;&#x542B; <code>@Configuration</code> &#x7C7B;&#x3002;&#x7531;&#x4E8E;&#x4F7F;&#x7528; <a href="http://asm.ow2.org/" target="_blank">ASM</a> &#x89E3;&#x6790;&#x6CE8;&#x89E3;&#x5143;&#x6570;&#x636E;&#xFF0C;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>value</code> &#x5C5E;&#x6027;&#x6765;&#x5F15;&#x7528;&#x771F;&#x5B9E;&#x7C7B;&#xFF0C;&#x5373;&#x4F7F;&#x8BE5;&#x7C7B;&#x5B9E;&#x9645;&#x4E0A;&#x53EF;&#x80FD;&#x4E0D;&#x4F1A;&#x51FA;&#x73B0;&#x5728;&#x6B63;&#x5728;&#x8FD0;&#x884C;&#x7684;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684; classpath &#x4E2D;&#x3002;&#x5982;&#x679C;&#x60A8;&#x5E0C;&#x671B;&#x4F7F;&#x7528; <code>String</code> &#x503C;&#x6765;&#x6307;&#x5B9A;&#x7C7B;&#x540D;&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>name</code> &#x5C5E;&#x6027;&#x3002;</p>
<p>&#x6B64;&#x673A;&#x5236;&#x4E0D;&#x4F1A;&#x4EE5;&#x76F8;&#x540C;&#x7684;&#x65B9;&#x5F0F;&#x5E94;&#x7528;&#x4E8E;&#x8FD4;&#x56DE;&#x7C7B;&#x578B;&#x662F;&#x6761;&#x4EF6;&#x7684;&#x76EE;&#x6807;&#x7684; <code>@Bean</code> &#x65B9;&#x6CD5;&#xFF1A;&#x5728;&#x65B9;&#x6CD5;&#x4E0A;&#x7684;&#x6761;&#x4EF6;&#x5E94;&#x7528;&#x4E4B;&#x524D;&#xFF0C;JVM &#x5C06;&#x52A0;&#x8F7D;&#x7C7B;&#x548C;&#x53EF;&#x80FD;&#x5904;&#x7406;&#x7684;&#x65B9;&#x6CD5;&#x5F15;&#x7528;&#xFF0C;&#x5982;&#x679C;&#x627E;&#x4E0D;&#x5230;&#x7C7B;&#xFF0C;&#x5C06;&#x53D1;&#x751F;&#x5931;&#x8D25;&#x3002;</p>
<p>&#x8981;&#x5904;&#x7406;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#xFF0C;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x5355;&#x72EC;&#x7684; <code>@Configuration</code> &#x7C7B;&#x6765;&#x9694;&#x79BB;&#x6761;&#x4EF6;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token comment">// Some conditions</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyAutoConfiguration</span> <span class="token punctuation">{</span>

    <span class="token comment">// Auto-configured beans</span>

    <span class="token annotation punctuation">@Configuration</span>
    <span class="token annotation punctuation">@ConditionalOnClass</span><span class="token punctuation">(</span><span class="token class-name">EmbeddedAcmeService</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
    <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">EmbeddedConfiguration</span> <span class="token punctuation">{</span>

        <span class="token annotation punctuation">@Bean</span>
        <span class="token annotation punctuation">@ConditionalOnMissingBean</span>
        <span class="token keyword">public</span> <span class="token class-name">EmbeddedAcmeService</span> <span class="token function">embeddedAcmeService</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x4F7F;&#x7528; <code>@ConditionalOnClass</code> &#x6216; <code>@ConditionalOnMissingClass</code> &#x4F5C;&#x4E3A;&#x5143;&#x6CE8;&#x89E3;&#x7684;&#x4E00;&#x90E8;&#x5206;&#x6765;&#x7EC4;&#x6210;&#x81EA;&#x5DF1;&#x7684;&#x7EC4;&#x5408;&#x6CE8;&#x89E3;&#xFF0C;&#x5219;&#x5FC5;&#x987B;&#x4F7F;&#x7528; <code>name</code> &#x6765;&#x5F15;&#x7528;&#x7C7B;&#xFF0C;&#x5728;&#x8FD9;&#x79CD;&#x60C5;&#x51B5;&#x5C06;&#x4E0D;&#x4F5C;&#x5904;&#x7406;&#x3002;</p>
</blockquote>
<p><a id="boot-features-bean-conditions"></a></p>
<h4 id="4932&#x3001;bean-&#x6761;&#x4EF6;">49.3.2&#x3001;Bean &#x6761;&#x4EF6;</h4>
<p><code>@ConditionalOnBean</code> &#x548C; <code>@ConditionalOnMissingBean</code> &#x6CE8;&#x89E3;&#x5141;&#x8BB8;&#x6839;&#x636E;&#x7279;&#x5B9A; bean &#x662F;&#x5426;&#x5B58;&#x5728;&#x6765;&#x5305;&#x542B; bean&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>value</code> &#x5C5E;&#x6027;&#x6309;&#x7C7B;&#x578B;&#x6216;&#x4F7F;&#x7528; <code>name</code> &#x6765;&#x6307;&#x5B9A; bean&#x3002;<code>search</code> &#x5C5E;&#x6027;&#x5141;&#x8BB8;&#x60A8;&#x9650;&#x5236;&#x5728;&#x641C;&#x7D22; bean &#x65F6;&#x5E94;&#x8003;&#x8651;&#x7684; <code>ApplicationContext</code> &#x5C42;&#x6B21;&#x7ED3;&#x6784;&#x3002;</p>
<p>&#x653E;&#x7F6E;&#x5728; <code>@Bean</code> &#x65B9;&#x6CD5;&#x4E0A;&#x65F6;&#xFF0C;&#x76EE;&#x6807;&#x7C7B;&#x578B;&#x9ED8;&#x8BA4;&#x4E3A;&#x65B9;&#x6CD5;&#x7684;&#x8FD4;&#x56DE;&#x7C7B;&#x578B;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MyAutoConfiguration</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token annotation punctuation">@ConditionalOnMissingBean</span>
    <span class="token keyword">public</span> <span class="token class-name">MyService</span> <span class="token function">myService</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span> <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x5728;&#x524D;&#x9762;&#x7684;&#x793A;&#x4F8B;&#x4E2D;&#xFF0C;&#x5982;&#x679C; <code>ApplicationContext</code> &#x4E2D;&#x4E0D;&#x5305;&#x542B; <code>MyService</code> &#x7C7B;&#x578B;&#x7684; bean&#xFF0C;&#x5219;&#x5C06;&#x521B;&#x5EFA; <code>myService</code> bean&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x60A8;&#x9700;&#x8981;&#x975E;&#x5E38;&#x5C0F;&#x5FC3;&#x5730;&#x6DFB;&#x52A0; bean &#x5B9A;&#x4E49;&#x7684;&#x987A;&#x5E8F;&#xFF0C;&#x56E0;&#x4E3A;&#x8FD9;&#x4E9B;&#x6761;&#x4EF6;&#x662F;&#x6839;&#x636E;&#x5230;&#x76EE;&#x524D;&#x4E3A;&#x6B62;&#x5DF2;&#x5904;&#x7406;&#x7684;&#x5185;&#x5BB9;&#x8FDB;&#x884C;&#x8BA1;&#x7B97;&#x7684;&#x3002;&#x56E0;&#x6B64;&#xFF0C;&#x6211;&#x4EEC;&#x5EFA;&#x8BAE;&#x5728;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7C7B;&#x4E0A;&#x4EC5;&#x4F7F;&#x7528; <code>@ConditionalOnBean</code> &#x548C; <code>@ConditionalOnMissingBean</code> &#x6CE8;&#x89E3;&#xFF08;&#x56E0;&#x4E3A;&#x8FD9;&#x4E9B;&#x6CE8;&#x89E3;&#x4FDD;&#x8BC1;&#x5728;&#x6DFB;&#x52A0;&#x6240;&#x6709;&#x7528;&#x6237;&#x5B9A;&#x4E49;&#x7684; bean &#x5B9A;&#x4E49;&#x540E;&#x52A0;&#x8F7D;&#xFF09;&#x3002;</p>
</blockquote>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p><code>@ConditionalOnBean</code> &#x548C; <code>@ConditionalOnMissingBean</code> &#x4E0D;&#x4F1A;&#x963B;&#x6B62;&#x521B;&#x5EFA; <code>@Configuration</code> &#x7C7B;&#x3002;&#x5728;&#x7C7B;&#x7EA7;&#x522B;&#x4F7F;&#x7528;&#x8FD9;&#x4E9B;&#x6761;&#x4EF6;&#x5E76;&#x4F7F;&#x7528;&#x6CE8;&#x89E3;&#x6807;&#x8BB0;&#x6BCF;&#x4E2A;&#x5305;&#x542B; <code>@Bean</code> &#x65B9;&#x6CD5;&#x7684;&#x552F;&#x4E00;&#x533A;&#x522B;&#x662F;&#xFF0C;&#x5982;&#x679C;&#x6761;&#x4EF6;&#x4E0D;&#x5339;&#x914D;&#xFF0C;&#x524D;&#x8005;&#x4F1A;&#x963B;&#x6B62;&#x5C06; <code>@Configuration</code> &#x7C7B;&#x6CE8;&#x518C;&#x4E3A; bean&#x3002;</p>
</blockquote>
<p><a id="boot-features-property-conditions"></a></p>
<h4 id="4933&#x3001;&#x5C5E;&#x6027;&#x6761;&#x4EF6;">49.3.3&#x3001;&#x5C5E;&#x6027;&#x6761;&#x4EF6;</h4>
<p><code>@ConditionalOnProperty</code> &#x6CE8;&#x89E3;&#x5141;&#x8BB8;&#x57FA;&#x4E8E; Spring Environment &#x5C5E;&#x6027;&#x5305;&#x542B;&#x914D;&#x7F6E;&#x3002;&#x4F7F;&#x7528; <code>prefix</code> &#x548C; <code>name</code> &#x5C5E;&#x6027;&#x6307;&#x5B9A;&#x9700;&#x8981;&#x68C0;&#x67E5;&#x7684;&#x5C5E;&#x6027;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;&#x5339;&#x914D;&#x5B58;&#x5728;&#x4E14;&#x4E0D;&#x7B49;&#x4E8E; <code>false</code> &#x7684;&#x6240;&#x6709;&#x5C5E;&#x6027;&#x3002;&#x60A8;&#x8FD8;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>havingValue</code> &#x548C; <code>matchIfMissing</code> &#x5C5E;&#x6027;&#x521B;&#x5EFA;&#x66F4;&#x9AD8;&#x7EA7;&#x7684;&#x68C0;&#x67E5;&#x3002;</p>
<p><a id="boot-features-resource-conditions"></a></p>
<h4 id="4934&#x3001;&#x8D44;&#x6E90;&#x6761;&#x4EF6;">49.3.4&#x3001;&#x8D44;&#x6E90;&#x6761;&#x4EF6;</h4>
<p><code>@ConditionalOnResource</code> &#x6CE8;&#x89E3;&#x4EC5;&#x5141;&#x8BB8;&#x5728;&#x5B58;&#x5728;&#x7279;&#x5B9A;&#x8D44;&#x6E90;&#x65F6;&#x5305;&#x542B;&#x914D;&#x7F6E;&#x3002;&#x53EF;&#x4EE5;&#x4F7F;&#x7528;&#x5E38;&#x7528;&#x7684; Spring &#x7EA6;&#x5B9A;&#x6765;&#x6307;&#x5B9A;&#x8D44;&#x6E90;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;<code>file:/home/user/test.dat</code>&#x3002;</p>
<p><a id="boot-features-web-application-conditions"></a></p>
<h4 id="4935&#x3001;web-&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x6761;&#x4EF6;">49.3.5&#x3001;Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x6761;&#x4EF6;</h4>
<p><code>@ConditionalOnWebApplication</code> &#x548C; <code>@ConditionalOnNotWebApplication</code> &#x6CE8;&#x89E3;&#x5728;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E3A; <strong>Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;</strong>&#x7684;&#x60C5;&#x51B5;&#x4E0B;&#x662F;&#x5426;&#x5305;&#x542B;&#x914D;&#x7F6E;&#x3002;Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x662F;&#x4F7F;&#x7528; Spring <code>WebApplicationContext</code>&#xFF0C;&#x5B9A;&#x4E49;&#x4E00;&#x4E2A; <code>session</code> &#x8303;&#x56F4;&#x6216;&#x5177;&#x6709; <code>StandardServletEnvironment</code> &#x7684;&#x4EFB;&#x4F55;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x3002;</p>
<p><a id="boot-features-spel-conditions"></a></p>
<h4 id="4936&#x3001;spel-&#x8868;&#x8FBE;&#x5F0F;&#x6761;&#x4EF6;">49.3.6&#x3001;SpEL &#x8868;&#x8FBE;&#x5F0F;&#x6761;&#x4EF6;</h4>
<p><code>@ConditionalOnExpression</code> &#x6CE8;&#x89E3;&#x5141;&#x8BB8;&#x6839;&#x636E; <a href="https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/core.html#expressions" target="_blank">SpEL &#x8868;&#x8FBE;&#x5F0F;</a>&#x7684;&#x7ED3;&#x679C;&#x5305;&#x542B;&#x914D;&#x7F6E;&#x3002;</p>
<p><a id="boot-features-test-autoconfig"></a></p>
<h4 id="494&#x3001;&#x6D4B;&#x8BD5;&#x81EA;&#x52A8;&#x914D;&#x7F6E;">49.4&#x3001;&#x6D4B;&#x8BD5;&#x81EA;&#x52A8;&#x914D;&#x7F6E;</h4>
<p>&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x53EF;&#x80FD;&#x53D7;&#x8BB8;&#x591A;&#x56E0;&#x7D20;&#x7684;&#x5F71;&#x54CD;&#xFF1A;&#x7528;&#x6237;&#x914D;&#x7F6E;&#xFF08;<code>@Bean</code> &#x5B9A;&#x4E49;&#x548C; <code>Environment</code> &#x81EA;&#x5B9A;&#x4E49;&#xFF09;&#x3001;&#x6761;&#x4EF6;&#x8BC4;&#x4F30;&#xFF08;&#x5B58;&#x5728;&#x7279;&#x5B9A;&#x7684;&#x7C7B;&#x5E93;&#xFF09;&#x7B49;&#x3002;&#x5177;&#x4F53;&#x800C;&#x8A00;&#xFF0C;&#x6BCF;&#x4E2A;&#x6D4B;&#x8BD5;&#x90FD;&#x5E94;&#x8BE5;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x5B9A;&#x4E49;&#x826F;&#x597D;&#x7684; <code>ApplicationContext</code>&#xFF0C;&#x5B83;&#x8868;&#x793A;&#x8FD9;&#x4E9B;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x7EC4;&#x5408;&#x3002;<code>ApplicationContextRunner</code> &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x597D;&#x7684;&#x5B9E;&#x73B0;&#x65B9;&#x6CD5;&#x3002;</p>
<p><code>ApplicationContextRunner</code> &#x901A;&#x5E38;&#x88AB;&#x5B9A;&#x4E49;&#x4E3A;&#x6D4B;&#x8BD5;&#x7C7B;&#x7684;&#x4E00;&#x4E2A;&#x5B57;&#x6BB5;&#xFF0C;&#x7528;&#x4E8E;&#x6536;&#x96C6;&#x57FA;&#x672C;&#x7684;&#x901A;&#x7528;&#x914D;&#x7F6E;&#x3002;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x786E;&#x4FDD;&#x59CB;&#x7EC8;&#x8C03;&#x7528; <code>UserServiceAutoConfiguration</code>&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token keyword">private</span> <span class="token keyword">final</span> <span class="token class-name">ApplicationContextRunner</span> contextRunner <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ApplicationContextRunner</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
        <span class="token punctuation">.</span><span class="token function">withConfiguration</span><span class="token punctuation">(</span><span class="token class-name">AutoConfigurations</span><span class="token punctuation">.</span><span class="token function">of</span><span class="token punctuation">(</span><span class="token class-name">UserServiceAutoConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x5FC5;&#x987B;&#x5B9A;&#x4E49;&#x591A;&#x4E2A;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x5219;&#x65E0;&#x9700;&#x6309;&#x7167;&#x4E0E;&#x8FD0;&#x884C;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x65F6;&#x5B8C;&#x5168;&#x76F8;&#x540C;&#x7684;&#x987A;&#x5E8F;&#x8C03;&#x7528;&#x5B83;&#x4EEC;&#x7684;&#x58F0;&#x660E;&#x3002;</p>
</blockquote>
<p>&#x6BCF;&#x4E2A;&#x6D4B;&#x8BD5;&#x90FD;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; runner &#x6765;&#x8868;&#x793A;&#x7279;&#x5B9A;&#x7684;&#x7528;&#x4F8B;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x4E0B;&#x9762;&#x7684;&#x793A;&#x4F8B;&#x8C03;&#x7528;&#x7528;&#x6237;&#x914D;&#x7F6E;&#xFF08;<code>UserConfiguration</code>&#xFF09;&#x5E76;&#x68C0;&#x67E5;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x662F;&#x5426;&#x6B63;&#x786E;&#x9000;&#x56DE;&#x3002;&#x8C03;&#x7528; <code>run</code> &#x63D0;&#x4F9B;&#x4E86;&#x4E00;&#x4E2A;&#x53EF;&#x4EE5;&#x4E0E; <code>Assert4J</code> &#x4E00;&#x8D77;&#x4F7F;&#x7528;&#x7684;&#x56DE;&#x8C03;&#x4E0A;&#x4E0B;&#x6587;&#x3002;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Test</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">defaultServiceBacksOff</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>contextRunner<span class="token punctuation">.</span><span class="token function">withUserConfiguration</span><span class="token punctuation">(</span><span class="token class-name">UserConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span> <span class="token operator">-&gt;</span> <span class="token punctuation">{</span>
                <span class="token function">assertThat</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hasSingleBean</span><span class="token punctuation">(</span><span class="token class-name">UserService</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
                <span class="token function">assertThat</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token class-name">UserService</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isSameAs</span><span class="token punctuation">(</span>
                        context<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token class-name">UserConfiguration</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">myUserService</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>

<span class="token annotation punctuation">@Configuration</span>
<span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">UserConfiguration</span> <span class="token punctuation">{</span>

    <span class="token annotation punctuation">@Bean</span>
    <span class="token keyword">public</span> <span class="token class-name">UserService</span> <span class="token function">myUserService</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">UserService</span><span class="token punctuation">(</span><span class="token string">&quot;mine&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p>&#x4E5F;&#x53EF;&#x4EE5;&#x8F7B;&#x677E;&#x81EA;&#x5B9A;&#x4E49; <code>Environment</code>&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Test</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">serviceNameCanBeConfigured</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>contextRunner<span class="token punctuation">.</span><span class="token function">withPropertyValues</span><span class="token punctuation">(</span><span class="token string">&quot;user.name=test123&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span> <span class="token operator">-&gt;</span> <span class="token punctuation">{</span>
        <span class="token function">assertThat</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hasSingleBean</span><span class="token punctuation">(</span><span class="token class-name">UserService</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">assertThat</span><span class="token punctuation">(</span>context<span class="token punctuation">.</span><span class="token function">getBean</span><span class="token punctuation">(</span><span class="token class-name">UserService</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">isEqualTo</span><span class="token punctuation">(</span><span class="token string">&quot;test123&quot;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>runner &#x8FD8;&#x53EF;&#x7528;&#x4E8E;&#x5C55;&#x793A; <code>ConditionEvaluationReport</code>&#x3002;&#x62A5;&#x544A;&#x53EF;&#x4EE5;&#x5728; <code>INFO</code> &#x6216; <code>DEBUG</code> &#x7EA7;&#x522B;&#x4E0B;&#x6253;&#x5370;&#x3002;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x5C55;&#x793A;&#x5982;&#x4F55;&#x4F7F;&#x7528; <code>ConditionEvaluationReportLoggingListener</code> &#x5728;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x6D4B;&#x8BD5;&#x4E2D;&#x6253;&#x5370;&#x62A5;&#x8868;&#x3002;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Test</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> autoConfigTest <span class="token punctuation">{</span>
    <span class="token class-name">ConditionEvaluationReportLoggingListener</span> initializer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ConditionEvaluationReportLoggingListener</span><span class="token punctuation">(</span>
            <span class="token class-name">LogLevel</span><span class="token punctuation">.</span>INFO<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token class-name">ApplicationContextRunner</span> contextRunner <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ApplicationContextRunner</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">withInitializer</span><span class="token punctuation">(</span>initializer<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span> <span class="token operator">-&gt;</span> <span class="token punctuation">{</span>
                    <span class="token comment">// Do something...</span>
            <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p><a id="_simulating_a_web_context"></a></p>
<h4 id="4941&#x3001;&#x6A21;&#x62DF;&#x4E00;&#x4E2A;-web-&#x4E0A;&#x4E0B;&#x6587;">49.4.1&#x3001;&#x6A21;&#x62DF;&#x4E00;&#x4E2A; Web &#x4E0A;&#x4E0B;&#x6587;</h4>
<p>&#x5982;&#x679C;&#x9700;&#x8981;&#x6D4B;&#x8BD5;&#x4E00;&#x4E2A;&#x4EC5;&#x5728; Servlet &#x6216;&#x54CD;&#x5E94;&#x5F0F; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x4E0A;&#x4E0B;&#x6587;&#x4E2D;&#x8FD0;&#x884C;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x8BF7;&#x5206;&#x522B;&#x4F7F;&#x7528; <code>WebApplicationContextRunner</code> &#x6216; <code>ReactiveWebApplicationContextRunner</code>&#x3002;</p>
<p><a id="_overriding_the_classpath"></a></p>
<h4 id="4942&#x3001;&#x8986;&#x76D6;-classpath">49.4.2&#x3001;&#x8986;&#x76D6; Classpath</h4>
<p>&#x8FD8;&#x53EF;&#x4EE5;&#x6D4B;&#x8BD5;&#x5728;&#x8FD0;&#x884C;&#x65F6;&#x4E0D;&#x5B58;&#x5728;&#x7279;&#x5B9A;&#x7C7B;&#x548C;/&#x6216;&#x5305;&#x65F6;&#x53D1;&#x751F;&#x7684;&#x60C5;&#x51B5;&#x3002; Spring Boot&#x9644;&#x5E26;&#x4E86;&#x4E00;&#x4E2A;&#x53EF;&#x4EE5;&#x7531;&#x8DD1;&#x6B65;&#x8005;&#x8F7B;&#x677E;&#x4F7F;&#x7528;&#x7684;FilteredClassLoader&#x3002; &#x5728;&#x4EE5;&#x4E0B;&#x793A;&#x4F8B;&#x4E2D;&#xFF0C;&#x6211;&#x4EEC;&#x58F0;&#x660E;&#x5982;&#x679C;UserService&#x4E0D;&#x5B58;&#x5728;&#xFF0C;&#x5219;&#x4F1A;&#x6B63;&#x786E;&#x7981;&#x7528;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF1A;</p>
<pre class="language-"><code class="lang-java"><span class="token annotation punctuation">@Test</span>
<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">serviceIsIgnoredIfLibraryIsNotPresent</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">this</span><span class="token punctuation">.</span>contextRunner<span class="token punctuation">.</span><span class="token function">withClassLoader</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token class-name">FilteredClassLoader</span><span class="token punctuation">(</span><span class="token class-name">UserService</span><span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
            <span class="token punctuation">.</span><span class="token function">run</span><span class="token punctuation">(</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span> <span class="token operator">-&gt;</span> <span class="token function">assertThat</span><span class="token punctuation">(</span>context<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">doesNotHaveBean</span><span class="token punctuation">(</span><span class="token string">&quot;userService&quot;</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-custom-starter"></a></p>
<h3 id="495&#x3001;&#x521B;&#x5EFA;&#x81EA;&#x5DF1;&#x7684;-starter">49.5&#x3001;&#x521B;&#x5EFA;&#x81EA;&#x5DF1;&#x7684; Starter</h3>
<p>&#x4E00;&#x4E2A;&#x5B8C;&#x6574;&#x7684; Spring Boot starter &#x7C7B;&#x5E93;&#x53EF;&#x80FD;&#x5305;&#x542B;&#x4EE5;&#x4E0B;&#x7EC4;&#x4EF6;&#xFF1A;</p>
<ul>
<li><code>autoconfigure</code> &#x6A21;&#x5757;&#xFF0C;&#x5305;&#x542B;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4EE3;&#x7801;&#x3002;</li>
<li><code>starter</code> &#x6A21;&#x5757;&#xFF0C;&#x5B83;&#x63D0;&#x4F9B;&#x5BF9; <code>autoconfigure</code> &#x6A21;&#x5757;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x4EE5;&#x53CA;&#x7C7B;&#x5E93;&#x548C;&#x5E38;&#x7528;&#x7684;&#x5176;&#x4ED6;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x3002;&#x7B80;&#x800C;&#x8A00;&#x4E4B;&#xFF0C;&#x6DFB;&#x52A0; starter &#x5E94;&#x8BE5;&#x63D0;&#x4F9B;&#x8BE5;&#x5E93;&#x5F00;&#x59CB;&#x4F7F;&#x7528;&#x6240;&#x9700;&#x7684;&#x4E00;&#x5207;&#x3002;</li>
</ul>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x60A8;&#x4E0D;&#x60F3;&#x5C06;&#x8FD9;&#x4E24;&#x4E2A;&#x6A21;&#x5757;&#x5206;&#x5F00;&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x5C06;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x4EE3;&#x7801;&#x548C;&#x4F9D;&#x8D56;&#x5173;&#x7CFB;&#x7BA1;&#x7406;&#x7EC4;&#x5408;&#x5728;&#x4E00;&#x4E2A;&#x6A21;&#x5757;&#x4E2D;&#x3002;</p>
</blockquote>
<p><a id="boot-features-custom-starter-naming"></a></p>
<h4 id="4951&#x3001;&#x547D;&#x540D;">49.5.1&#x3001;&#x547D;&#x540D;</h4>
<p>&#x60A8;&#x5E94;&#x8BE5;&#x786E;&#x4FDD;&#x4E3A;&#x60A8;&#x7684; starter &#x63D0;&#x4F9B;&#x4E00;&#x4E2A;&#x5408;&#x9002;&#x7684;&#x547D;&#x540D;&#x7A7A;&#x95F4;&#x3002;&#x5373;&#x4F7F;&#x60A8;&#x4F7F;&#x7528;&#x5176;&#x4ED6; Maven <code>groupId</code>&#xFF0C;&#x4E5F;&#x4E0D;&#x8981;&#x4F7F;&#x7528; <code>spring-boot</code> &#x4F5C;&#x4E3A;&#x6A21;&#x5757;&#x540D;&#x79F0;&#x7684;&#x5F00;&#x5934;&#x3002;&#x6211;&#x4EEC;&#x53EF;&#x80FD;&#x4F1A;&#x4E3A;&#x60A8;&#x4EE5;&#x540E;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684;&#x5185;&#x5BB9;&#x63D0;&#x4F9B;&#x5B98;&#x65B9;&#x652F;&#x6301;&#x3002;</p>
<p>&#x6839;&#x636E;&#x7ECF;&#x9A8C;&#xFF0C;&#x60A8;&#x5E94;&#x8BE5;&#x5728; starter &#x540E;&#x547D;&#x540D;&#x4E00;&#x4E2A;&#x7EC4;&#x5408;&#x6A21;&#x5757;&#x3002;&#x4F8B;&#x5982;&#xFF0C;&#x5047;&#x8BBE;&#x60A8;&#x6B63;&#x5728;&#x4E3A; <strong>acme</strong> &#x521B;&#x5EFA;&#x4E00;&#x4E2A; starter&#xFF0C;&#x5E76;&#x4E14;&#x60A8;&#x5C06;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x6A21;&#x5757;&#x547D;&#x540D;&#x4E3A; <code>acme-spring-boot-autoconfigure</code>&#xFF0C;&#x5C06; starter &#x547D;&#x540D;&#x4E3A; <code>acme-spring-boot-starter</code>&#x3002;&#x5982;&#x679C;&#x60A8;&#x53EA;&#x6709;&#x4E00;&#x4E2A;&#x7EC4;&#x5408;&#x8FD9;&#x4E24;&#x8005;&#x7684;&#x6A21;&#x5757;&#xFF0C;&#x8BF7;&#x5C06;&#x5176;&#x547D;&#x540D;&#x4E3A; <code>acme-spring-boot-starter</code>&#x3002;</p>
<p>&#x6B64;&#x5916;&#xFF0C;&#x5982;&#x679C;&#x60A8;&#x7684; starter &#x63D0;&#x4F9B;&#x914D;&#x7F6E; key&#xFF0C;&#x8BF7;&#x4E3A;&#x5B83;&#x4EEC;&#x4F7F;&#x7528;&#x552F;&#x4E00;&#x7684;&#x547D;&#x540D;&#x7A7A;&#x95F4;&#x3002;&#x5C24;&#x5176;&#x662F;&#xFF0C;&#x4E0D;&#x8981;&#x5C06;&#x60A8;&#x7684; key &#x5305;&#x542B;&#x5728; Spring Boot &#x4F7F;&#x7528;&#x7684;&#x547D;&#x540D;&#x7A7A;&#x95F4;&#x4E2D;&#xFF08;&#x4F8B;&#x5982; <code>server</code>&#x3001;<code>management</code>&#x3001;<code>spring</code> &#x7B49;&#xFF09;&#x3002;&#x5982;&#x679C;&#x60A8;&#x4F7F;&#x7528;&#x4E86;&#x76F8;&#x540C;&#x7684;&#x547D;&#x540D;&#x7A7A;&#x95F4;&#xFF0C;&#x6211;&#x4EEC;&#x5C06;&#x6765;&#x53EF;&#x80FD;&#x4F1A;&#x4EE5;&#x7834;&#x574F;&#x60A8;&#x7684;&#x6A21;&#x5757;&#x7684;&#x65B9;&#x5F0F;&#x6765;&#x4FEE;&#x6539;&#x8FD9;&#x4E9B;&#x547D;&#x540D;&#x7A7A;&#x95F4;&#x3002;</p>
<p>&#x786E;<a href="#configuration-metadata-annotation-processor">&#x4FDD;&#x89E6;&#x53D1;&#x5143;&#x6570;&#x636E;&#x751F;&#x6210;</a>&#xFF0C;&#x4EE5;&#x4FBF;&#x4E3A;&#x60A8;&#x7684; key &#x63D0;&#x4F9B; IDE &#x5E2E;&#x52A9;&#x3002;&#x60A8;&#x53EF;&#x80FD;&#x60F3;&#x67E5;&#x770B;&#x751F;&#x6210;&#x7684;&#x5143;&#x6570;&#x636E;&#xFF08;<code>META-INF/spring-configuration-metadata.json</code>&#xFF09;&#x4EE5;&#x786E;&#x4FDD;&#x60A8;&#x7684; key &#x8BB0;&#x5F55;&#x662F;&#x5426;&#x6B63;&#x786E;&#x3002;</p>
<p><a id="boot-features-custom-starter-module-autoconfigure"></a></p>
<h4 id="4952&#x3001;autoconfigure-&#x6A21;&#x5757;">49.5.2&#x3001;<code>autoconfigure</code> &#x6A21;&#x5757;</h4>
<p><code>autoconfigure</code> &#x6A21;&#x5757;&#x5305;&#x542B;&#x7C7B;&#x5E93;&#x5F00;&#x59CB;&#x4F7F;&#x7528;&#x6240;&#x9700;&#x7684;&#x6240;&#x6709;&#x5185;&#x5BB9;&#x3002;&#x5B83;&#x8FD8;&#x53EF;&#x4EE5;&#x5305;&#x542B;&#x914D;&#x7F6E; key &#x5B9A;&#x4E49;&#xFF08;&#x4F8B;&#x5982; <code>@ConfigurationProperties</code>&#xFF09;&#x548C;&#x4EFB;&#x4F55;&#x53EF;&#x7528;&#x4E8E;&#x8FDB;&#x4E00;&#x6B65;&#x81EA;&#x5B9A;&#x4E49;&#x7EC4;&#x4EF6;&#x521D;&#x59CB;&#x5316;&#x65B9;&#x5F0F;&#x7684;&#x56DE;&#x8C03;&#x63A5;&#x53E3;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x60A8;&#x5E94;&#x8BE5;&#x5C06;&#x7C7B;&#x5E93;&#x7684;&#x4F9D;&#x8D56;&#x9879;&#x6807;&#x8BB0;&#x4E3A;&#x53EF;&#x9009;&#xFF0C;&#x4EE5;&#x4FBF;&#x60A8;&#x53EF;&#x4EE5;&#x66F4;&#x8F7B;&#x677E;&#x5730;&#x5728;&#x9879;&#x76EE;&#x4E2D;&#x5305;&#x542B; <code>autoconfigure</code> &#x6A21;&#x5757;&#x3002;&#x5982;&#x679C;&#x4EE5;&#x8FD9;&#x79CD;&#x65B9;&#x5F0F;&#x6267;&#x884C;&#xFF0C;&#x5219;&#x4E0D;&#x63D0;&#x4F9B;&#x7C7B;&#x5E93;&#xFF0C;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Spring Boot &#x5C06;&#x4F1A;&#x9000;&#x51FA;&#x3002;</p>
</blockquote>
<p>Spring Boot &#x4F7F;&#x7528;&#x6CE8;&#x89E3;&#x5904;&#x7406;&#x5668;&#x6765;&#x6536;&#x96C6;&#x5143;&#x6570;&#x636E;&#x6587;&#x4EF6;&#xFF08;<code>META-INF/spring-autoconfigure-metadata.properties</code>&#xFF09;&#x4E2D;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684;&#x6761;&#x4EF6;&#x3002;&#x5982;&#x679C;&#x8BE5;&#x6587;&#x4EF6;&#x5B58;&#x5728;&#xFF0C;&#x5219;&#x7528;&#x4E8E;&#x5FEB;&#x901F;&#x8FC7;&#x6EE4;&#x4E0D;&#x5339;&#x914D;&#x7684;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#xFF0C;&#x7F29;&#x77ED;&#x542F;&#x52A8;&#x65F6;&#x95F4;&#x3002;&#x5EFA;&#x8BAE;&#x5728;&#x5305;&#x542B;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684;&#x6A21;&#x5757;&#x4E2D;&#x6DFB;&#x52A0;&#x4EE5;&#x4E0B;&#x4F9D;&#x8D56;&#x9879;&#xFF1A;</p>
<pre class="language-"><code class="lang-xml"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>dependency</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>groupId</span><span class="token punctuation">&gt;</span></span>org.springframework.boot<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>groupId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>artifactId</span><span class="token punctuation">&gt;</span></span>spring-boot-autoconfigure-processor<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>artifactId</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>optional</span><span class="token punctuation">&gt;</span></span>true<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>optional</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>dependency</span><span class="token punctuation">&gt;</span></span>
</code></pre>
<p>&#x4F7F;&#x7528; Gradle 4.5 &#x53CA;&#x66F4;&#x65E9;&#x7248;&#x672C;&#x65F6;&#xFF0C;&#x5E94;&#x5728; <code>compileOnly</code> &#x914D;&#x7F6E;&#x4E2D;&#x58F0;&#x660E;&#x4F9D;&#x8D56;&#x9879;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-groovy">dependencies <span class="token punctuation">{</span>
    compileOnly <span class="token string">&quot;org.springframework.boot:spring-boot-autoconfigure-processor&quot;</span>
<span class="token punctuation">}</span>
</code></pre>
<p>&#x4F7F;&#x7528; Gradle 4.6 &#x53CA;&#x66F4;&#x9AD8;&#x7248;&#x672C;&#x65F6;&#xFF0C;&#x5E94;&#x5728; <code>annotationProcessor</code> &#x914D;&#x7F6E;&#x4E2D;&#x58F0;&#x660E;&#x4F9D;&#x8D56;&#x9879;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-groovy">dependencies <span class="token punctuation">{</span>
    annotationProcessor <span class="token string">&quot;org.springframework.boot:spring-boot-autoconfigure-processor&quot;</span>
<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-custom-starter-module-starter"></a></p>
<h4 id="4953&#x3001;starter-&#x6A21;&#x5757;">49.5.3&#x3001;Starter &#x6A21;&#x5757;</h4>
<p>starter &#x771F;&#x7684;&#x662F;&#x4E00;&#x4E2A;&#x7A7A; jar&#x3002;&#x5B83;&#x7684;&#x552F;&#x4E00;&#x76EE;&#x7684;&#x662F;&#x4E3A;&#x4F7F;&#x7528;&#x7C7B;&#x5E93;&#x63D0;&#x4F9B;&#x5FC5;&#x8981;&#x7684;&#x4F9D;&#x8D56;&#x9879;&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x5C06;&#x5176;&#x89C6;&#x4E3A;&#x4F7F;&#x7528;&#x7C7B;&#x5E93;&#x7684;&#x4E00;&#x5207;&#x57FA;&#x7840;&#x3002;</p>
<p>&#x4E0D;&#x8981;&#x5BF9;&#x6DFB;&#x52A0; starter &#x7684;&#x9879;&#x76EE;&#x62B1;&#x6709;&#x5047;&#x8BBE;&#x60F3;&#x6CD5;&#x3002;&#x5982;&#x679C;&#x60A8;&#x81EA;&#x52A8;&#x914D;&#x7F6E;&#x7684;&#x5E93;&#x7ECF;&#x5E38;&#x9700;&#x8981;&#x5176;&#x4ED6; starter&#xFF0C;&#x8BF7;&#x4E00;&#x5E76;&#x58F0;&#x660E;&#x5B83;&#x4EEC;&#x3002;&#x5982;&#x679C;&#x53EF;&#x9009;&#x4F9D;&#x8D56;&#x9879;&#x7684;&#x6570;&#x91CF;&#x5F88;&#x591A;&#xFF0C;&#x5219;&#x63D0;&#x4F9B;&#x4E00;&#x7EC4;&#x9002;&#x5F53;&#x7684;&#x9ED8;&#x8BA4;&#x4F9D;&#x8D56;&#x9879;&#x53EF;&#x80FD;&#x5F88;&#x96BE;&#xFF0C;&#x56E0;&#x4E3A;&#x60A8;&#x672C;&#x5E94;&#x8BE5;&#x907F;&#x514D;&#x5305;&#x542B;&#x5BF9;&#x5E38;&#x7528;&#x5E93;&#x7684;&#x4F7F;&#x7528;&#x4E0D;&#x5FC5;&#x8981;&#x7684;&#x4F9D;&#x8D56;&#x9879;&#x3002;&#x6362;&#x800C;&#x8A00;&#x4E4B;&#xFF0C;&#x60A8;&#x4E0D;&#x5E94;&#x8BE5;&#x5305;&#x542B;&#x53EF;&#x9009;&#x7684;&#x4F9D;&#x8D56;&#x9879;&#x3002;</p>
<p><strong>&#x6CE8;&#x610F;</strong></p>
<blockquote>
<p>&#x65E0;&#x8BBA;&#x54EA;&#x79CD;&#x65B9;&#x5F0F;&#xFF0C;&#x60A8;&#x7684; starter &#x5FC5;&#x987B;&#x76F4;&#x63A5;&#x6216;&#x95F4;&#x63A5;&#x5F15;&#x7528;&#x6838;&#x5FC3; Spring Boot starter&#xFF08;<code>spring-boot-starter</code>&#xFF09;&#xFF08;&#x5982;&#x679C;&#x60A8;&#x7684; starter &#x4F9D;&#x8D56;&#x4E8E;&#x53E6;&#x4E00;&#x4E2A; starter &#xFF0C;&#x5219;&#x65E0;&#x9700;&#x6DFB;&#x52A0;&#x5B83;&#xFF09;&#x3002;&#x5982;&#x679C;&#x53EA;&#x4F7F;&#x7528;&#x81EA;&#x5B9A;&#x4E49; starter &#x521B;&#x5EFA;&#x9879;&#x76EE;&#xFF0C;&#x5219; Spring Boot &#x7684;&#x6838;&#x5FC3;&#x529F;&#x80FD;&#x5C06;&#x901A;&#x8FC7;&#x5B58;&#x5728;&#x7684;&#x6838;&#x5FC3; starter &#x6765;&#x5B9E;&#x73B0;&#x3002;</p>
</blockquote>
<p><a id="boot-features-kotlin"></a></p>
<h2 id="50&#x3001;kotlin-&#x652F;&#x6301;">50&#x3001;Kotlin &#x652F;&#x6301;</h2>
<p><a href="https://kotlinlang.org/" target="_blank">Kotlin</a> &#x662F;&#x4E00;&#x79CD;&#x9488;&#x5BF9; JVM&#xFF08;&#x548C;&#x5176;&#x4ED6;&#x5E73;&#x53F0;&#xFF09;&#x7684;&#x9759;&#x6001;&#x7C7B;&#x578B;&#x8BED;&#x8A00;&#xFF0C;&#x5B83;&#x53EF;&#x7F16;&#x5199;&#x51FA;&#x7B80;&#x6D01;&#x800C;&#x4F18;&#x96C5;&#x7684;&#x4EE3;&#x7801;&#xFF0C;&#x540C;&#x65F6;&#x63D0;&#x4F9B;&#x4E0E;&#x4F7F;&#x7528; Java &#x7F16;&#x5199;&#x7684;&#x73B0;&#x6709;&#x5E93;&#x7684;<a href="https://kotlinlang.org/docs/reference/java-interop.html" target="_blank">&#x4E92;&#x64CD;&#x4F5C;&#x6027;</a>&#x3002;</p>
<p>Spring Boot &#x901A;&#x8FC7;&#x5229;&#x7528;&#x5176;&#x4ED6; Spring &#x9879;&#x76EE;&#xFF08;&#x5982; Spring Framework&#x3001;Spring Data &#x548C; Reactor&#xFF09;&#x7684;&#x652F;&#x6301;&#x6765;&#x63D0;&#x4F9B; Kotlin &#x652F;&#x6301;&#x3002;&#x6709;&#x5173;&#x66F4;&#x591A;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/languages.html#kotlin" target="_blank">Spring Framework Kotlin &#x652F;&#x6301;&#x6587;&#x6863;</a>&#x3002;</p>
<p>&#x5F00;&#x59CB;&#x5B66;&#x4E60; Spring Boot &#x548C; Kotlin &#x6700;&#x7B80;&#x5355;&#x65B9;&#x6CD5;&#x662F;&#x9075;&#x5FAA;&#x8FD9;&#x4E2A;<a href="https://spring.io/guides/tutorials/spring-boot-kotlin/" target="_blank">&#x5168;&#x9762;&#x6559;&#x7A0B;</a>&#x3002;&#x60A8;&#x53EF;&#x4EE5;&#x901A;&#x8FC7; <a href="https://start.spring.io/#!language=kotlin" target="_blank">start.spring.io</a> &#x521B;&#x5EFA;&#x65B0;&#x7684; Kotlin &#x9879;&#x76EE;&#x3002;&#x5982;&#x679C;&#x60A8;&#x9700;&#x8981;&#x652F;&#x6301;&#xFF0C;&#x8BF7;&#x514D;&#x8D39;&#x52A0;&#x5165; <a href="http://slack.kotlinlang.org/" target="_blank">Kotlin Slack</a> &#x7684; #spring &#x9891;&#x9053;&#x6216;&#x4F7F;&#x7528; <a href="https://stackoverflow.com/questions/tagged/spring+kotlin" target="_blank">Stack Overflow</a> &#x4E0A;&#x7684; <code>spring</code> &#x548C; <code>kotlin</code> &#x6807;&#x7B7E;&#x63D0;&#x95EE;&#x3002;</p>
<p><a id="boot-features-kotlin-requirements"></a></p>
<h3 id="501&#x3001;&#x8981;&#x6C42;">50.1&#x3001;&#x8981;&#x6C42;</h3>
<p>Spring Boot &#x652F;&#x6301; Kotlin 1.2.x&#x3002;&#x8981;&#x4F7F;&#x7528; Kotlin&#xFF0C;classpath &#x4E0B;&#x5FC5;&#x987B;&#x5B58;&#x5728; <code>org.jetbrains.kotlin:kotlin-stdlib</code> &#x548C; <code>org.jetbrains.kotlin:kotlin-reflect</code>&#x3002;&#x4E5F;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <code>kotlin-stdlib</code> &#x7684;&#x53D8;&#x4F53; <code>kotlin-stdlib-jdk7</code> &#x548C; <code>kotlin-stdlib-jdk8</code>&#x3002;</p>
<p>&#x7531;&#x4E8E; <a href="https://discuss.kotlinlang.org/t/classes-final-by-default/166" target="_blank">Kotlin &#x7C7B;&#x9ED8;&#x8BA4;&#x4E3A; final</a>&#xFF0C;&#x56E0;&#x6B64;&#x60A8;&#x53EF;&#x80FD;&#x9700;&#x8981;&#x914D;&#x7F6E; <a href="https://kotlinlang.org/docs/reference/compiler-plugins.html#spring-support" target="_blank">kotlin-spring</a> &#x63D2;&#x4EF6;&#x4EE5;&#x81EA;&#x52A8;&#x6253;&#x5F00; <code>Spring-annotated</code> &#x7C7B;&#xFF0C;&#x4EE5;&#x4FBF;&#x53EF;&#x4EE5;&#x4EE3;&#x7406;&#x5B83;&#x4EEC;&#x3002;</p>
<p>&#x5728; Kotlin &#x4E2D;&#x5E8F;&#x5217;&#x5316;/&#x53CD;&#x5E8F;&#x5217;&#x5316; JSON &#x6570;&#x636E;&#x9700;&#x8981;&#x4F7F;&#x7528; <a href="https://github.com/FasterXML/jackson-module-kotlin" target="_blank">Jackson &#x7684; Kotlin &#x6A21;&#x5757;</a>&#x3002;&#x5728; classpath &#x4E2D;&#x627E;&#x5230;&#x5B83;&#x65F6;&#x4F1A;&#x81EA;&#x52A8;&#x6CE8;&#x518C;&#x3002;&#x5982;&#x679C; Jackson &#x548C; Kotlin &#x5B58;&#x5728;&#x4F46; Jackson Kotlin &#x6A21;&#x5757;&#x4E0D;&#x5B58;&#x5728;&#xFF0C;&#x5219;&#x4F1A;&#x8BB0;&#x5F55;&#x8B66;&#x544A;&#x6D88;&#x606F;&#x3002;</p>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x5982;&#x679C;&#x5728; <a href="https://start.spring.io/#!language=kotlin" target="_blank">start.spring.io</a> &#x4E0A;&#x521B;&#x5EFA; Kotlin &#x9879;&#x76EE;&#xFF0C;&#x5219;&#x9ED8;&#x8BA4;&#x63D0;&#x4F9B;&#x8FD9;&#x4E9B;&#x4F9D;&#x8D56;&#x9879;&#x548C;&#x63D2;&#x4EF6;&#x3002;</p>
</blockquote>
<p><a id="boot-features-kotlin-null-safety"></a></p>
<h3 id="502&#x3001;null-&#x5B89;&#x5168;">50.2&#x3001;Null &#x5B89;&#x5168;</h3>
<p>Kotlin &#x7684;&#x4E00;&#x4E2A;&#x5173;&#x952E;&#x7279;&#x6027;&#x662F; <a href="https://kotlinlang.org/docs/reference/null-safety.html" target="_blank">null &#x5B89;&#x5168;</a>&#x3002;&#x5B83;&#x5728;&#x7F16;&#x8BD1;&#x65F6;&#x5904;&#x7406;&#x7A7A;&#x503C;&#xFF0C;&#x800C;&#x4E0D;&#x662F;&#x5C06;&#x95EE;&#x9898;&#x63A8;&#x8FDF;&#x5230;&#x8FD0;&#x884C;&#x65F6;&#x5E76;&#x9047;&#x5230; <code>NullPointerException</code>&#x3002;&#x8FD9;&#x6709;&#x52A9;&#x4E8E;&#x6D88;&#x9664;&#x5E38;&#x89C1;&#x7684;&#x9519;&#x8BEF;&#x6765;&#x6E90;&#xFF0C;&#x800C;&#x65E0;&#x9700;&#x652F;&#x4ED8;&#x50CF; <code>Optional</code> &#x8FD9;&#x6837;&#x7684;&#x5305;&#x88C5;&#x5668;&#x7684;&#x6210;&#x672C;&#x3002;Kotlin &#x8FD8;&#x5141;&#x8BB8;&#x4F7F;&#x7528;&#x6709;&#x53EF;&#x7A7A;&#x503C;&#x7684;&#xFF0C;&#x5982; <a href="http://www.baeldung.com/kotlin-null-safety" target="_blank">Kotlin null &#x5B89;&#x5168;&#x7EFC;&#x5408;&#x6307;&#x5357;</a>&#x4E2D;&#x6240;&#x8FF0;&#x3002;</p>
<p>&#x867D;&#x7136; Java &#x4E0D;&#x5141;&#x8BB8;&#x5728;&#x5176;&#x7C7B;&#x578B;&#x7CFB;&#x7EDF;&#x4E2D;&#x8868;&#x793A; null &#x5B89;&#x5168;&#xFF0C;&#x4F46; Spring Framework&#x3001;Spring Data &#x548C; Reactor &#x73B0;&#x5728;&#x901A;&#x8FC7;&#x6613;&#x4E8E;&#x4F7F;&#x7528;&#x7684;&#x5DE5;&#x5177;&#x7684;&#x6CE8;&#x89E3;&#x63D0;&#x4F9B;&#x5176; API &#x7684;&#x5B89;&#x5168;&#x6027;&#x3002;&#x9ED8;&#x8BA4;&#x60C5;&#x51B5;&#x4E0B;&#xFF0C;Kotlin &#x4E2D;&#x4F7F;&#x7528;&#x7684; Java API &#x7C7B;&#x578B;&#x88AB;&#x8BC6;&#x522B;&#x4E3A;&#x653E;&#x5BBD;&#x7A7A;&#x68C0;&#x67E5;&#x7684;<a href="https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types" target="_blank">&#x5E73;&#x53F0;&#x7C7B;&#x578B;</a>&#x3002;<a href="https://kotlinlang.org/docs/reference/java-interop.html#jsr-305-support" target="_blank">Kotlin &#x5BF9; JSR 305 &#x6CE8;&#x89E3;&#x7684;&#x652F;&#x6301;</a>&#x4E0E;&#x53EF;&#x7A7A;&#x6CE8;&#x89E3;&#x76F8;&#x7ED3;&#x5408;&#xFF0C;&#x4E3A; Kotlin &#x4E2D; Spring API &#x76F8;&#x5173;&#x7684;&#x4EE3;&#x7801;&#x63D0;&#x4F9B;&#x4E86;&#x7A7A;&#x5B89;&#x5168;&#x3002;</p>
<p>&#x53EF;&#x4EE5;&#x901A;&#x8FC7;&#x4F7F;&#x7528;&#x4EE5;&#x4E0B;&#x9009;&#x9879;&#x6DFB;&#x52A0; <code>-Xjsr305</code> &#x7F16;&#x8BD1;&#x5668;&#x6807;&#x5FD7;&#x6765;&#x914D;&#x7F6E; JSR 305 &#x68C0;&#x67E5;&#xFF1A;<code>-Xjsr305={strict|warn|ignore}</code>&#x3002;&#x9ED8;&#x8BA4;&#x884C;&#x4E3A;&#x4E0E; <code>-Xjsr305=warn</code> &#x76F8;&#x540C;&#x3002;&#x5728;&#x4ECE; Spring API &#x63A8;&#x65AD;&#x51FA;&#x7684; Kotlin &#x7C7B;&#x578B;&#x4E2D;&#x9700;&#x8981;&#x8003;&#x8651; null &#x5B89;&#x5168;&#x7684; <code>strict</code> &#x503C;&#xFF0C;&#x4F46;&#x662F;&#x5E94;&#x8BE5;&#x4F7F;&#x7528; Spring API &#x53EF;&#x7A7A;&#x58F0;&#x660E;&#x751A;&#x81F3;&#x53EF;&#x4EE5;&#x5728;&#x6B21;&#x8981;&#x7248;&#x672C;&#x4E4B;&#x95F4;&#x53D1;&#x5C55;&#x5E76;&#x4E14;&#x5C06;&#x6765;&#x53EF;&#x80FD;&#x6DFB;&#x52A0;&#x66F4;&#x591A;&#x68C0;&#x67E5;&#x7684;&#x65B9;&#x6848;&#x3002;</p>
<p><strong>&#x8B66;&#x544A;</strong></p>
<blockquote>
<p>&#x5C1A;&#x4E0D;&#x652F;&#x6301;&#x6CDB;&#x578B;&#x7C7B;&#x578B;&#x53C2;&#x6570;&#x3001;<code>varargs</code> &#x548C;&#x6570;&#x7EC4;&#x5143;&#x7D20;&#x53EF;&#x7A7A;&#x6027;&#x3002;&#x6709;&#x5173;&#x6700;&#x65B0;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x89C1; <a href="https://jira.spring.io/browse/SPR-15942" target="_blank">SPR-15942</a>&#x3002;&#x53E6;&#x8BF7;&#x6CE8;&#x610F;&#xFF0C;Spring Boot &#x81EA;&#x5DF1;&#x7684; API <a href="https://github.com/spring-projects/spring-boot/issues/10712" target="_blank">&#x5C1A;&#x672A;&#x6CE8;&#x89E3;</a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-kotlin-api"></a></p>
<h3 id="503&#x3001;kotlin-api">50.3&#x3001;Kotlin API</h3>
<p><a id="boot-features-kotlin-api-runapplication"></a></p>
<h4 id="5031&#x3001;runapplication">50.3.1&#x3001;runApplication</h4>
<p>Spring Boot &#x63D0;&#x4F9B;&#x4E86;&#x4F7F;&#x7528; <code>runApplication<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>MyApplication</span><span class="token punctuation">&gt;</span></span>(*args)</code> &#x8FD0;&#x884C;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#x7684;&#x60EF;&#x7528;&#x65B9;&#x6CD5;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-kotlin"><span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>autoconfigure<span class="token punctuation">.</span>SpringBootApplication
<span class="token keyword">import</span> org<span class="token punctuation">.</span>springframework<span class="token punctuation">.</span>boot<span class="token punctuation">.</span>runApplication

<span class="token annotation builtin">@SpringBootApplication</span>
<span class="token keyword">class</span> MyApplication

<span class="token keyword">fun</span> <span class="token function">main</span><span class="token punctuation">(</span>args<span class="token operator">:</span> Array<span class="token operator">&lt;</span>String<span class="token operator">&gt;</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    runApplication<span class="token operator">&lt;</span>MyApplication<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<p>&#x8FD9;&#x662F; <code>SpringApplication.run(MyApplication::class.java, *args)</code> &#x7684;&#x66FF;&#x4EE3;&#x65B9;&#x5F0F;&#x3002;&#x5B83;&#x8FD8;&#x5141;&#x8BB8;&#x81EA;&#x5B9A;&#x4E49;&#x5E94;&#x7528;&#x7A0B;&#x5E8F;&#xFF0C;&#x5982;&#x4E0B;&#x6240;&#x793A;&#xFF1A;</p>
<pre class="language-"><code class="lang-kotlin">runApplication<span class="token operator">&lt;</span>MyApplication<span class="token operator">&gt;</span><span class="token punctuation">(</span><span class="token operator">*</span>args<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token function">setBannerMode</span><span class="token punctuation">(</span>OFF<span class="token punctuation">)</span>
<span class="token punctuation">}</span>
</code></pre>
<p><a id="boot-features-kotlin-api-extensions"></a></p>
<h4 id="5032&#x3001;&#x6269;&#x5C55;">50.3.2&#x3001;&#x6269;&#x5C55;</h4>
<p>Kotlin <a href="https://kotlinlang.org/docs/reference/extensions.html" target="_blank">&#x6269;&#x5C55;</a>&#x63D0;&#x4F9B;&#x4E86;&#x4F7F;&#x7528;&#x9644;&#x52A0;&#x529F;&#x80FD;&#x6269;&#x5C55;&#x73B0;&#x6709;&#x7C7B;&#x7684;&#x80FD;&#x529B;&#x3002;Spring Boot Kotlin API &#x5229;&#x7528;&#x8FD9;&#x4E9B;&#x6269;&#x5C55;&#x4E3A;&#x73B0;&#x6709; API &#x6DFB;&#x52A0;&#x65B0;&#x7684; Kotlin &#x7279;&#x5B9A;&#x4FBF;&#x5229;&#x3002;</p>
<p>&#x63D0;&#x4F9B;&#x7684; <code>TestRestTemplate</code> &#x6269;&#x5C55;&#x7C7B;&#x4F3C;&#x4E8E; Spring Framework &#x4E3A; <code>RestOperations</code> &#x63D0;&#x4F9B;&#x7684;&#x3002;&#x9664;&#x6B64;&#x4E4B;&#x5916;&#xFF0C;&#x6269;&#x5C55;&#x4F7F;&#x5F97;&#x5229;&#x7528; Kotlin reified &#x7C7B;&#x578B;&#x53C2;&#x6570;&#x53D8;&#x4E3A;&#x53EF;&#x80FD;&#x3002;</p>
<p><a id="boot-features-kotlin-dependency-management"></a></p>
<h3 id="504&#x3001;&#x4F9D;&#x8D56;&#x7BA1;&#x7406;">50.4&#x3001;&#x4F9D;&#x8D56;&#x7BA1;&#x7406;</h3>
<p>&#x4E3A;&#x4E86;&#x907F;&#x514D;&#x5728; classpath &#x4E0A;&#x6DF7;&#x5408;&#x4E0D;&#x540C;&#x7248;&#x672C;&#x7684; Kotlin &#x4F9D;&#x8D56;&#x9879;&#xFF0C;&#x63D0;&#x4F9B;&#x4E86;&#x4EE5;&#x4E0B; Kotlin &#x4F9D;&#x8D56;&#x9879;&#x7684;&#x4F9D;&#x8D56;&#x9879;&#x7BA1;&#x7406;&#xFF1A;</p>
<ul>
<li><code>kotlin-reflect</code></li>
<li><code>kotlin-runtime</code></li>
<li><code>kotlin-stdlib</code></li>
<li><code>kotlin-stdlib-jdk7</code></li>
<li><code>kotlin-stdlib-jdk8</code></li>
<li><code>kotlin-stdlib-jre7</code></li>
<li><code>kotlin-stdlib-jre8</code></li>
</ul>
<p>&#x4F7F;&#x7528; Maven&#xFF0C;&#x53EF;&#x4EE5;&#x901A;&#x8FC7; <code>kotlin.version</code> &#x5C5E;&#x6027;&#x81EA;&#x5B9A;&#x4E49; Kotlin &#x7248;&#x672C;&#xFF0C;&#x5E76;&#x4E3A; <code>kotlin-maven-plugin</code> &#x63D0;&#x4F9B;&#x63D2;&#x4EF6;&#x7BA1;&#x7406;&#x3002;&#x4F7F;&#x7528; Gradle&#xFF0C;Spring Boot &#x63D2;&#x4EF6;&#x4F1A;&#x81EA;&#x52A8;&#x5C06; <code>kotlin.version</code> &#x4E0E; Kotlin &#x63D2;&#x4EF6;&#x7684;&#x7248;&#x672C;&#x4FDD;&#x4E00;&#x81F4;&#x3002;</p>
<p><a id="boot-features-kotlin-configuration-properties"></a></p>
<h3 id="505&#x3001;configurationproperties">50.5&#x3001;<code>@ConfigurationProperties</code></h3>
<p><code>@ConfigurationProperties</code> &#x76EE;&#x524D;&#x4EC5;&#x9002;&#x7528;&#x4E8E; <code>lateinit</code> &#x6216;&#x53EF;&#x7A7A;&#x7684; <code>var</code> &#x5C5E;&#x6027;&#xFF08;&#x5EFA;&#x8BAE;&#x4F7F;&#x7528;&#x524D;&#x8005;&#xFF09;&#xFF0C;&#x56E0;&#x4E3A;<a href="https://github.com/spring-projects/spring-boot/issues/8762" target="_blank">&#x5C1A;&#x4E0D;&#x652F;&#x6301;</a>&#x7531;&#x6784;&#x9020;&#x51FD;&#x6570;&#x521D;&#x59CB;&#x5316;&#x7684;&#x4E0D;&#x53EF;&#x53D8;&#x7C7B;&#x3002;</p>
<pre class="language-"><code class="lang-kotlin"><span class="token annotation builtin">@ConfigurationProperties</span><span class="token punctuation">(</span><span class="token string">&quot;example.kotlin&quot;</span><span class="token punctuation">)</span>
<span class="token keyword">class</span> KotlinExampleProperties <span class="token punctuation">{</span>

    <span class="token keyword">lateinit</span> <span class="token keyword">var</span> name<span class="token operator">:</span> String

    <span class="token keyword">lateinit</span> <span class="token keyword">var</span> description<span class="token operator">:</span> String

    <span class="token keyword">val</span> myService <span class="token operator">=</span> <span class="token function">MyService</span><span class="token punctuation">(</span><span class="token punctuation">)</span>

    <span class="token keyword">class</span> MyService <span class="token punctuation">{</span>

        <span class="token keyword">lateinit</span> <span class="token keyword">var</span> apiToken<span class="token operator">:</span> String

        <span class="token keyword">lateinit</span> <span class="token keyword">var</span> uri<span class="token operator">:</span> URI

    <span class="token punctuation">}</span>

<span class="token punctuation">}</span>
</code></pre>
<p><strong>&#x63D0;&#x793A;</strong></p>
<blockquote>
<p>&#x8981;&#x4F7F;&#x7528;&#x6CE8;&#x89E3;&#x5904;&#x7406;&#x5668;&#x751F;&#x6210;<a href="#configuration-metadata-annotation-processor">&#x60A8;&#x81EA;&#x5DF1;&#x7684;&#x5143;&#x6570;&#x636E;</a>&#xFF0C;&#x5E94;&#x4F7F;&#x7528; <code>spring-boot-configuration-processor</code> &#x4F9D;&#x8D56;<a href="https://kotlinlang.org/docs/reference/kapt.html" target="_blank">&#x914D;&#x7F6E; <code>kapt</code></a>&#x3002;</p>
</blockquote>
<p><a id="boot-features-kotlin-testing"></a></p>
<h3 id="506&#x3001;&#x6D4B;&#x8BD5;">50.6&#x3001;&#x6D4B;&#x8BD5;</h3>
<p>&#x867D;&#x7136;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; JUnit 4&#xFF08;<code>spring-boot-starter-test</code> &#x63D0;&#x4F9B;&#x7684;&#x9ED8;&#x8BA4;&#x914D;&#x7F6E;&#xFF09;&#x6765;&#x6D4B;&#x8BD5; Kotlin &#x4EE3;&#x7801;&#xFF0C;&#x4F46;&#x5EFA;&#x8BAE;&#x4F7F;&#x7528; JUnit 5&#x3002;JUnit 5 &#x5141;&#x8BB8;&#x6D4B;&#x8BD5;&#x7C7B;&#x5B9E;&#x4F8B;&#x5316;&#x4E00;&#x6B21;&#xFF0C;&#x5E76;&#x5728;&#x6240;&#x6709;&#x7C7B;&#x7684;&#x6D4B;&#x8BD5;&#x4E2D;&#x590D;&#x7528;&#x3002;&#x8FD9;&#x4F7F;&#x5F97;&#x53EF;&#x4EE5;&#x5728;&#x975E;&#x9759;&#x6001;&#x65B9;&#x6CD5;&#x4E0A;&#x4F7F;&#x7528; <code>@BeforeAll</code> &#x548C; <code>@AfterAll</code> &#x6CE8;&#x89E3;&#xFF0C;&#x8FD9;&#x975E;&#x5E38;&#x9002;&#x5408; Kotlin&#x3002;</p>
<p>&#x8981;&#x4F7F;&#x7528; JUnit 5&#xFF0C;&#x8BF7;&#x4ECE; <code>spring-boot-starter-test</code> &#x4E2D;&#x6392;&#x9664; <code>junit:junit</code> &#x4F9D;&#x8D56;&#x9879;&#xFF0C;&#x7136;&#x540E;&#x6DFB;&#x52A0; JUnit 5 &#x4F9D;&#x8D56;&#x9879;&#xFF0C;&#x5E76;&#x76F8;&#x5E94;&#x5730;&#x914D;&#x7F6E; Maven &#x6216; Gradle &#x63D2;&#x4EF6;&#x3002;&#x6709;&#x5173;&#x66F4;&#x591A;&#x8BE6;&#x7EC6;&#x4FE1;&#x606F;&#xFF0C;&#x8BF7;&#x53C2;&#x9605; <a href="https://junit.org/junit5/docs/current/user-guide/#dependency-metadata-junit-jupiter-samples" target="_blank">JUnit 5 &#x6587;&#x6863;</a>&#x3002;&#x60A8;&#x8FD8;&#x9700;&#x8981;<a href="https://junit.org/junit5/docs/current/user-guide/#writing-tests-test-instance-lifecycle-changing-default" target="_blank">&#x5C06;&#x6D4B;&#x8BD5;&#x5B9E;&#x4F8B;&#x751F;&#x547D;&#x5468;&#x671F;&#x5207;&#x6362;&#x4E3A; <strong>per-class</strong></a>&#x3002;</p>
<p>&#x4E3A;&#x4E86;&#x6A21;&#x62DF; Kotlin &#x7C7B;&#xFF0C;&#x5EFA;&#x8BAE;&#x4F7F;&#x7528; <a href="https://mockk.io/" target="_blank">Mockk</a>&#x3002;&#x5982;&#x679C;&#x9700;&#x8981; Mockk &#x7B49;&#x6548;&#x7684; Mockito &#x7279;&#x5B9A;&#x7684; <a href="boot-features-testing-spring-boot-applications-mocking-beans"><code>@MockBean</code> &#x548C; <code>@SpyBean</code> &#x6CE8;&#x89E3;</a>&#xFF0C;&#x5219;&#x53EF;&#x4EE5;&#x4F7F;&#x7528; <a href="https://github.com/Ninja-Squad/springmockk" target="_blank">SpringMockK</a>&#xFF0C;&#x5B83;&#x63D0;&#x4F9B;&#x7C7B;&#x4F3C;&#x7684; <code>@MockkBean</code> &#x548C; <code>@SpykBean</code> &#x6CE8;&#x89E3;&#x3002;</p>
<p><a id="boot-features-kotlin-resources"></a></p>
<h3 id="507&#x3001;&#x8D44;&#x6E90;">50.7&#x3001;&#x8D44;&#x6E90;</h3>
<p><a id="boot-features-kotlin-resources-further-reading"></a></p>
<h4 id="5071&#x3001;&#x8FDB;&#x9636;&#x9605;&#x8BFB;">50.7.1&#x3001;&#x8FDB;&#x9636;&#x9605;&#x8BFB;</h4>
<ul>
<li><a href="https://kotlinlang.org/docs/reference/" target="_blank">Kotlin &#x8BED;&#x8A00;&#x53C2;&#x8003;</a></li>
<li><a href="http://slack.kotlinlang.org/" target="_blank">Kotlin Slack</a>&#xFF08;&#x6709;&#x4E13;&#x7528;&#x7684; #spring &#x9891;&#x9053;&#xFF09;</li>
<li><a href="https://stackoverflow.com/questions/tagged/spring+kotlin" target="_blank">Stackoverflow &#x4E0A; <code>spring</code> &#x548C; <code>kotlin</code> &#x6807;&#x7B7E;</a></li>
<li><a href="https://try.kotlinlang.org/" target="_blank">&#x5728;&#x6D4F;&#x89C8;&#x5668;&#x4E2D;&#x5C1D;&#x8BD5; Kotlin</a></li>
<li><a href="https://blog.jetbrains.com/kotlin/" target="_blank">Kotlin &#x535A;&#x5BA2;</a></li>
<li><a href="https://kotlin.link/" target="_blank">Awesome Kotlin</a></li>
<li><a href="https://spring.io/guides/tutorials/spring-boot-kotlin/" target="_blank">&#x6559;&#x7A0B;&#xFF1A;&#x4F7F;&#x7528; Spring Boot &#x548C; Kotlin &#x6784;&#x5EFA; Web &#x5E94;&#x7528;&#x7A0B;&#x5E8F;</a></li>
<li><a href="https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin" target="_blank">&#x4F7F;&#x7528; Kotlin &#x5F00;&#x53D1; Spring Boot &#x5E94;&#x7528;&#x7A0B;&#x5E8F;</a></li>
<li><a href="https://spring.io/blog/2016/03/20/a-geospatial-messenger-with-kotlin-spring-boot-and-postgresql" target="_blank">&#x4F7F;&#x7528; Kotlin&#x3001;Spring Boot &#x548C; PostgreSQL &#x5F00;&#x53D1;&#x5730;&#x7406;&#x4FE1;&#x4F7F;</a></li>
<li><a href="https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0" target="_blank">&#x5728; Spring Framework 5.0 &#x4E2D;&#x5F15;&#x5165; Kotlin &#x652F;&#x6301;</a></li>
<li><a href="https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-apis-the-functional-way" target="_blank">Spring Framework 5 Kotlin API &#x5B9E;&#x73B0;&#x51FD;&#x6570;&#x5F0F;</a></li>
</ul>
<p><a id="boot-features-kotlin-resources-examples"></a></p>
<h4 id="5072&#x3001;&#x793A;&#x4F8B;">50.7.2&#x3001;&#x793A;&#x4F8B;</h4>
<ul>
<li><a href="https://github.com/sdeleuze/spring-boot-kotlin-demo" target="_blank">spring-boot-kotlin-demo</a>&#xFF1A;&#x5E38;&#x89C4;&#x7684; Spring Boot + Spring Data JPA &#x9879;&#x76EE;</li>
<li><a href="https://github.com/mixitconf/mixit" target="_blank">mixit</a>&#xFF1A;Spring Boot 2 + WebFlux + Reactive Spring Data MongoDB</li>
<li><a href="https://github.com/sdeleuze/spring-kotlin-fullstack" target="_blank">spring-kotlin-fullstack</a>&#xFF1A;WebFlux Kotlin &#x5168;&#x6808;&#x793A;&#x4F8B;&#xFF0C;&#x5728;&#x524D;&#x7AEF;&#x4F7F;&#x7528; Kotlin2js &#x4EE3;&#x66FF; JavaScript &#x548C; TypeScript</li>
<li><a href="https://github.com/spring-petclinic/spring-petclinic-kotlin" target="_blank">spring-petclinic-kotlin</a>&#xFF1A;Spring PetClinic &#x793A;&#x4F8B;&#x5E94;&#x7528;&#x7684; Kotlin &#x7248;&#x672C;</li>
<li><a href="https://github.com/sdeleuze/spring-kotlin-deepdive" target="_blank">spring-kotlin-deepdive</a>&#xFF1A;&#x5C06;Boot 1.0 + Java &#x9010;&#x6B65;&#x8FC1;&#x79FB;&#x5230; Boot 2.0 + Kotlin</li>
</ul>
<p><a id="boot-features-whats-next"></a></p>
<h2 id="51&#x3001;&#x4E0B;&#x4E00;&#x6B65;">51&#x3001;&#x4E0B;&#x4E00;&#x6B65;</h2>
<p>&#x5982;&#x679C;&#x60A8;&#x60F3;&#x4E86;&#x89E3;&#x672C;&#x8282;&#x4E2D;&#x8BA8;&#x8BBA;&#x7684;&#x4EFB;&#x4F55;&#x7C7B;&#x76EE;&#x7684;&#x66F4;&#x591A;&#x4FE1;&#x606F;&#xFF0C;&#x53EF;&#x4EE5;&#x67E5;&#x770B; <a href="https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/api" target="_blank">Spring Boot API &#x6587;&#x6863;</a>&#xFF0C;&#x4E5F;&#x53EF;&#x4EE5;&#x76F4;&#x63A5;&#x6D4F;&#x89C8;<a href="https://github.com/spring-projects/spring-boot/tree/v2.1.3.RELEASE" target="_blank">&#x6E90;&#x4EE3;&#x7801;</a>&#x3002;&#x5982;&#x679C;&#x60A8;&#x6709;&#x5177;&#x4F53;&#x95EE;&#x9898;&#xFF0C;&#x8BF7;&#x67E5;&#x770B; <a href="howto.md">how-to</a> &#x90E8;&#x5206;&#x3002;</p>
<p>&#x5982;&#x679C;&#x60A8;&#x5BF9; Spring Boot &#x7684;&#x6838;&#x5FC3;&#x529F;&#x80FD;&#x611F;&#x5230;&#x6EE1;&#x610F;&#xFF0C;&#x53EF;&#x4EE5;&#x7EE7;&#x7EED;&#x9605;&#x8BFB;&#x6709;&#x5173;&#x751F;&#x4EA7;&#x5C31;&#x7EEA;&#x529F;&#x80FD;&#x7684;&#x5185;&#x5BB9;&#x3002;</p>
<footer class="page-footer"><span class="copyright">powered by Gitbook</span><span class="footer-modification">File Modify: 
2020-01-07 23:30:15
</span></footer>
                                
                                </section>
                            
    </div>
    <div class="search-results">
        <div class="has-results">
            
            <h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
            <ul class="search-results-list"></ul>
            
        </div>
        <div class="no-results">
            
            <h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
            
        </div>
    </div>
</div>

                        </div>
                    </div>
                
            </div>

            
                
                <a href="using-spring-boot.html#using-boot-whats-next" class="navigation navigation-prev " aria-label="Previous page: 22、下一步">
                    <i class="fa fa-angle-left"></i>
                </a>
                
                
                <a href="spring-boot-features.html#boot-features-spring-application" class="navigation navigation-next " aria-label="Next page: 23、SpringApplication">
                    <i class="fa fa-angle-right"></i>
                </a>
                
            
        
    </div>

    <script>
        var gitbook = gitbook || [];
        gitbook.push(function() {
            gitbook.page.hasChanged({"page":{"title":"四、Spring Boot 特性","level":"1.6","depth":1,"next":{"title":"23、SpringApplication","level":"1.6.1","depth":2,"anchor":"#boot-features-spring-application","path":"pages/spring-boot-features.md","ref":"pages/spring-boot-features.md#boot-features-spring-application","articles":[{"title":"23.1、启动失败","level":"1.6.1.1","depth":3,"anchor":"#boot-features-startup-failure","path":"pages/spring-boot-features.md","ref":"pages/spring-boot-features.md#boot-features-startup-failure","articles":[]},{"title":"23.2、自定义 banner","level":"1.6.1.2","depth":3,"anchor":"#boot-features-banner","path":"pages/spring-boot-features.md","ref":"pages/spring-boot-features.md#boot-features-banner","articles":[]},{"title":"23.3、自定义 SpringApplication","level":"1.6.1.3","depth":3,"anchor":"#boot-features-customizing-spring-application","path":"pages/spring-boot-features.md","ref":"pages/spring-boot-features.md#boot-features-customizing-spring-application","articles":[]},{"title":"23.4、Fluent Builder API","level":"1.6.1.4","depth":3,"anchor":"#boot-features-customizing-spring-application","path":"pages/spring-boot-features.md","ref":"pages/spring-boot-features.md#boot-features-customizing-spring-application","articles":[]},{"title":"23.5、应用程序事件与监听器","level":"1.6.1.5","depth":3,"anchor":"#boot-features-application-events-and-listeners","path":"pages/spring-boot-features.md","ref":"pages/spring-boot-features.md#boot-features-application-events-and-listeners","articles":[]},{"title":"23.6、Web 环境","level":"1.6.1.6","depth":3,"anchor":"#boot-features-web-environment","path":"pages/spring-boot-features.md","ref":"pages/spring-boot-features.md#boot-features-web-environment","articles":[]},{"title":"23.7、访问应用程序参数","level":"1.6.1.7","depth":3,"anchor":"#boot-features-application-arguments","path":"pages/spring-boot-features.md","ref":"pages/spring-boot-features.md#boot-features-application-arguments","articles":[]},{"title":"23.8、使用 ApplicationRunner 或 ApplicationRunner","level":"1.6.1.8","depth":3,"anchor":"#boot-features-command-line-runner","path":"pages/spring-boot-features.md","ref":"pages/spring-boot-features.md#boot-features-command-line-runner","articles":[]},{"title":"23.9、应用程序退出","level":"1.6.1.9","depth":3,"anchor":"#boot-features-application-exit","path":"pages/spring-boot-features.md","ref":"pages/spring-boot-features.md#boot-features-application-exit","articles":[]},{"title":"23.10、管理功能","level":"1.6.1.10","depth":3,"anchor":"#boot-features-application-admin","path":"pages/spring-boot-features.md","ref":"pages/spring-boot-features.md#boot-features-application-admin","articles":[]}]},"previous":{"title":"22、下一步","level":"1.5.10","depth":2,"anchor":"#using-boot-whats-next","path":"pages/using-spring-boot.md","ref":"pages/using-spring-boot.md#using-boot-whats-next","articles":[]},"dir":"ltr"},"config":{"plugins":["github","splitter","tbfed-pagefooter","-lunr","-search","search-plus","github-buttons","copy-code-button","prism","-highlight","-livereload","livereload"],"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"pluginsConfig":{"tbfed-pagefooter":{},"prism":{"css":["prismjs/themes/prism-twilight.css"]},"github":{"url":"https://gitee.com/lichongbing/springboot"},"splitter":{},"fontsettings":{"theme":"white","family":"sans","size":2},"github-buttons":{"repo":"lichongbing/springboot","types":["star","watch"],"size":"small"},"copy-code-button":{},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false},"search-plus":{},"image-captions":{"caption":"_CAPTION_"}},"theme":"default","author":"lichongbing.com","pdf":{"pageNumbers":true,"fontSize":16,"fontFamily":"Arial","paperSize":"a4","chapterMark":"pagebreak","pageBreaksBefore":"/","margin":{"right":62,"left":62,"top":36,"bottom":36}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"title":"Spring Boot 中文文档","language":"zh-hans","links":{"sharing":{"all":true,"facebook":true,"google":true,"twitter":true,"qzone":true,"weibo":true}},"gitbook":"*","description":"Spring Boot 中文文档","extension":null},"file":{"path":"pages/spring-boot-features.md","mtime":"2020-01-07T14:30:15.086Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2020-01-07T14:47:40.777Z"},"basePath":"..","book":{"language":""}});
        });
    </script>
</div>

        
    <script src="../gitbook/gitbook.js"></script>
    <script src="../gitbook/theme.js"></script>
    
        
        <script src="../gitbook/gitbook-plugin-github/plugin.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-splitter/splitter.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-search-plus/jquery.mark.min.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-search-plus/search.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-github-buttons/plugin.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-copy-code-button/toggle.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-sharing/buttons.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
        
    

    </body>
</html>

